P7860 [COCI2015-2016#2] ARTUR

纯粹的發表於2024-06-05

原題連結

教訓

1.計算幾何,能用乘法就不用除法
2.計算幾何,開longlong
3.計算幾何,注意直線的特殊性

code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct node
{
    ll x1,y1,x2,y2;
}sk[5005];
int check(node a,node b)
{
    if(a.x2<b.x1||a.x1>b.x2) return 0;

    if(a.x1==a.x2)
    {
        ll x=a.x1;
        if(b.x1==b.x2)
        {
            if(min(a.y1,a.y2)<b.y1) return 1;
            else return 2;
        }
        ll ya=min(a.y1,a.y2);

        if(ya*(b.x2-b.x1)<(b.y1*b.x2-b.y2*b.x1+b.y2*x-b.y1*x)) return 1;
        else return 2;
    }
    else if(b.x1==b.x2)
    {
        ll x=b.x1;
        ll yb=min(b.y1,b.y2);

        if(yb*(a.x2-a.x1)<(a.y1*a.x2-a.y2*a.x1+a.y2*x-a.y1*x)) return 2;
        else return 1;
    }

    ll x;
    if(a.x1<b.x1)x=b.x1;
    else x=a.x1;

    ll ya=((a.y1-a.y2)*x-a.y1*a.x2+a.x1*a.y2)*(b.x1-b.x2),yb=((b.y1-b.y2)*x-b.y1*b.x2+b.x1*b.y2)*(a.x1-a.x2);

    if(ya<yb) return 1;
    return 2;
}

vector<int> G[250005];
int in[250005]={0};
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>sk[i].x1>>sk[i].y1>>sk[i].x2>>sk[i].y2;
        if(sk[i].x2<sk[i].x1)
        {
            swap(sk[i].x1,sk[i].x2);
            swap(sk[i].y1,sk[i].y2);
        }
    }

    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            int res=check(sk[i],sk[j]);
            if(res==1)
            {
                G[i].push_back(j);
                in[j]++;
            }
            else if(res==2)
            {
                G[j].push_back(i);
                in[i]++;
            }
        }
    }

    queue<int> q;
    int cnt=0;
    for(int i=1;i<=n;i++) if(!in[i]) q.push(i);
    while(q.size())
    {
        int now=q.front();
        q.pop();
        cout<<now<<" ";
        cnt++;
        for(auto next:G[now])
        {
            in[next]--;
            if(!in[next]) q.push(next);
        }
    }
    return 0;
}