2012-2013 ACM-ICPC Pacific Northwest Regional Contest Partition (极角排序)

Description

The Ents are known as the shepherds of the forest. Treebeard, the oldest living Ent in Middle Earth, needs to determine which trees he is to shepherd and which trees are to be shepherded by his young fellow Ent, Bregalad. They have a rectangular portion of Fangorn forest containing an even number of trees that they need to divide into two pieces using a single straight boundary line. In order to equitably distribute the workload, Treebeard and Bregalad have decided that each of their halves of the forest need to contain equal area and contain an equal number of trees. If a tree lies exactly on the dividing line, then that tree is counted in one or the other of the halves of the forest but not both. Any tree exactly on the dividing line may be assigned to either Treebeard or Bregalad.
Input

Input will consist of multiple test cases. Each test case begins with a line with 3 space-separated integers N, W, and H, denoting the number of trees, the width of the forest, and the height of the forest, respectively. The forest’s four corners are (0,0),(W,0),(0,H),
and (W,H) . Following this line are N lines each with a pair of space-separated integers xi and yi denoting the coordinates of the ith tree. Furthermore, • 2≤N≤50000,2≤W≤10000,2≤H≤10000, N is even, W and H are not both even. • 0

#include<bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 50000+32;
LL w,h;
int n;
struct Point
{
    int id;
    long long x, y;
    Point() : x(), y() {}
    Point(long long _x, long long _y) : x(_x), y(_y) {}

    Point operator + (const Point &A) const
    {
        return Point(x + A.x, y + A.y);
    }
    Point operator - (const Point &A) const
    {
        return Point(x - A.x, y - A.y);
    }
    long long operator % (const Point &A) const
    {
        return x * A.x + y * A.y;
    }
    long long operator * (const Point &A) const//叉积
    {
        return x * A.y - y * A.x;
    }
    Point operator * (long long k) const
    {
        return Point(x * k, y * k);
    }
    void read()
    {
        scanf("%lld%lld", &x, &y);
    }
    int half() const
    {
        return y > 0 || (y == 0 && x > 0);
    }
    bool operator < (const Point &A) const
    {
        if (half() != A.half() ) return half() < A.half();
        return *this * A > 0;
    }
    void print()
    {
        printf("%lld %lld\n", x, y);
    }
}P[maxn];

bool cmp(int a, int b)
{
    Point A = P[a], B = P[b];
    return A < B;
}
//判断叉积正负
bool good(int a, int b)
{
    Point A = P[a], B = P[b];
    return A * B >= 0;
}
bool goods(int a, int b)
{
    Point A = P[a], B = P[b];
    return A * B > 0;
}
bool notgoods(int a,int b)
{

    Point A = P[a], B = P[b];
    return A * B < 0;
}
bool notgood(int a,int b)
{
     Point A = P[a], B = P[b];
    return A * B <= 0;
}
int ans[maxn];
Point Q[maxn];
int p[maxn];
int main()
{
    while(~scanf("%d%d%d",&n,&w,&h))
    {
        if(n+w+h==0) return 0;
        memset(ans,0,sizeof(ans));
        for(int i = 0;i<n;i++){
            P[i].read();
            Q[i] = P[i];
            p[i] = i;
            P[i] = P[i]*2-Point(w,h);
            P[i].id = i;
        }
        sort(P,P+n);
        for(int i = 0;i<n;i++){
            int la = (i-1+n)%n;
            int r = (i+n/2-1)%n;
            int rr = (r+1)%n;
            if(notgood(p[i],p[rr])&&good(p[i],p[r])){
                for(int k = 0;k<n/2;k++){
                    ans[k+i] = 1;
                }
                break;
           // }
            if(good(p[i],p[rr])&&notgood(p[la],p[rr])){
               for(int k = 0;k<n/2;k++){
                    ans[p[i+k]] = 1;
                }
                break;
            }
        }
        for(int i = 0;i<n;i++){
            if(ans[i]){
                printf("%lld %lld\n",Q[i].x,Q[i].y);
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/w571523631/article/details/80018147