QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#721961#9520. Concave Hullzzfs#RE 0ms3588kbC++174.4kb2024-11-07 17:18:092024-11-07 17:18:09

Judging History

你现在查看的是最新测评结果

  • [2024-11-07 17:18:09]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:3588kb
  • [2024-11-07 17:18:09]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
#define int int64_t
struct point
{
    int x, y;
    int ind;
    point() {}
    point(int xx, int yy) 
    {
        x = xx, y = yy;
    }
    point operator+(const point& r) const
    {
        return point(x + r.x, y + r.y);
    }
    point operator-(const point& r) const
    {
        return point(x - r.x, y - r.y);
    }
    int operator*(const point& r) const
    {
        return x * r.x + y * r.y;
    }
    bool operator<(const point& r) const
    {
        return make_pair(x, y) < make_pair(r.x, r.y);
    }
    int operator^(const point& r) const
    {
        return x * r.y - y * r.x;
    }
    int len2() const
    {
        return (*this) * (*this);
    }
    int dis2(const point& r) const
    {
        return (r - (*this)).len2();
    }
    int toleft(const point& r) const
    {
        const auto t = (*this) ^ r;
        return (t > 0) - (t < 0);
    }
};

struct polygon
{
    vector<point> p;
    polygon() = default;
    polygon(vector<point> _p) : p(_p) {};
    size_t nxt(const size_t i) const
    {
        return i == p.size() - 1 ? 0 : i + 1;
    }
    size_t pre(const size_t i) const
    {
        return i == 0 ? p.size() - 1 : i - 1;
    }
    int area_m2() const
    {
        int sum = 0;
        for (int i = 0; i < p.size(); i++)
        {
            sum += p[i] ^ p[nxt(i)];
        }
        return sum;
        
    }
};

polygon convexhull(vector<point> p, vector<bool>& is_use)
{
    for (int i = 0; i < p.size(); i++)
    {
        p[i].ind = i;
    }
    
    is_use.clear();
    vector<point> st;
    if(p.empty()) return polygon{st};
    sort(p.begin(), p.end());
    const auto check = [] (const vector<point> &st, const point &u)
    {
        const auto back1 = st.back(), back2 = *prev(st.end(), 2);
        return (back1 - back2).toleft(u - back2) <= 0;
    };
    for (const point& u : p)
    {
        while (st.size() > 1 && check(st, u))
        {
            st.pop_back();
        }
        st.push_back(u);
        
    }
    size_t k = st.size();
    p.pop_back();
    reverse(p.begin(), p.end());
    for(const point& u : p)
    {
        while (st.size() > k && check(st, u))
        {
            st.pop_back();
        }
        st.push_back(u);
        
    }
    st.pop_back();
    is_use.assign(st.size(), false);
    for (const point& u : st)
    {
        is_use[u.ind] = true;
    }
    return polygon{st};
}

struct line
{
    point p, v;
    line() = default;
    line(point beg, point end) 
    {
        p = beg;
        v = end - beg;
    }
    long double dis(const point &a) const
    {
        return abs(v ^ (a - p)) / sqrt(v.len2());
    }
};



void sol()
{
    vector<point> parr;
    int N;
    cin >> N;
    for (int i = 0; i < N; i++)
    {
        int x, y;
        cin >> x >> y;
        parr.push_back(point(x, y));
    }
    vector<bool> point_is_use;
    auto pol_hull_outsite = convexhull(parr, point_is_use);
    vector<point> p_insite;
    for (int i = 0; i < parr.size(); i++)
    {
        if(point_is_use[i] == false)
        {
            p_insite.push_back(parr[i]);
        }
    }
    if(p_insite.size() == 0)
    {
        cout << "-1\n";
        return;
    }
    auto pol_hull_in = convexhull(p_insite, point_is_use);
    int p_in = 0;
    int outsite_Sm2 = abs(pol_hull_outsite.area_m2());
    int min_sub_Sm2 = outsite_Sm2;
    for (int i = 0; i < pol_hull_outsite.p.size(); i++)
    {
        auto op1 = pol_hull_outsite.p[i];
        auto op2 = pol_hull_outsite.p[pol_hull_outsite.nxt(i)];
        for(; ; p_in = pol_hull_in.nxt(p_in))
        {
            auto ip0 = pol_hull_in.p[pol_hull_in.pre(p_in)];
            auto ip1 = pol_hull_in.p[p_in];
            auto ip2 = pol_hull_in.p[pol_hull_in.nxt(p_in)];
            auto dis0 = line(op1, op2).dis(ip0);
            auto dis1 = line(op1, op2).dis(ip1);
            auto dis2 = line(op1, op2).dis(ip2);
            if(dis1 <= dis0 && dis1 <= dis2)
            {
                break;
            }
        }
        
        auto p_3jx = polygon({op1, op2, pol_hull_in.p[p_in]});
        min_sub_Sm2 = min(min_sub_Sm2, abs(p_3jx.area_m2()));


    }
    cout << outsite_Sm2 - min_sub_Sm2 << "\n";
    
}
int32_t main()
{
    int T;
    cin >> T;
    while (T--)
    {
        sol();
    }
    
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3588kb

input:

2
6
-2 0
1 -2
5 2
0 4
1 2
3 1
4
0 0
1 0
0 1
1 1

output:

40
-1

result:

ok 2 lines

Test #2:

score: -100
Runtime Error

input:

10
243
-494423502 -591557038
-493438474 -648991734
-493289308 -656152126
-491185085 -661710614
-489063449 -666925265
-464265894 -709944049
-447472922 -737242534
-415977509 -773788538
-394263365 -797285016
-382728841 -807396819
-373481975 -814685302
-368242265 -818267002
-344482838 -833805545
-279398...

output:


result: