【hiho1582】Territorial Dispute(凸包)

题目链接

#1582 : Territorial Dispute

时间限制:1000ms

单点时限:1000ms

内存限制:256MB

描述

In 2333, the C++ Empire and the Java Republic become the most powerful country in the world. They compete with each other in the colonizing the Mars.

There are n colonies on the Mars, numbered from 1 to n. The i-th colony's location is given by a pair of integers (xi, yi). Notice that latest technology in 2333 finds out that the surface of Mars is a two-dimensional plane, and each colony can be regarded as a point on this plane. Each colony will be allocated to one of the two countries during the Mars Development Summit which will be held in the next month.

After all colonies are allocated, two countries must decide a border line. The Mars Development Convention of 2048 had declared that: A valid border line of two countries should be a straight line, which makes colonies ofdifferent countries be situated on different sides of the line.

The evil Python programmer, David, notices that there may exist a plan of allocating colonies, which makes the valid border line do not exist. According to human history, this will cause a territorial dispute, and eventually lead to war.

David wants to change the colony allocation plan secretly during the Mars Development Summit. Now he needs you to give him a specific plan of allocation which will cause a territorial dispute. He promises that he will give you 1000000007 bitcoins for the plan.

输入

The first line of the input is an integer T, the number of the test cases (T ≤ 50).

For each test case, the first line contains one integer n (1 ≤ n ≤ 100), the number of colonies.

扫描二维码关注公众号,回复: 4386091 查看本文章

Then n lines follow. Each line contains two integers xi, yi (0 ≤ xi, yi ≤ 1000), meaning the location of the i-th colony. There are no two colonies share the same location.

There are no more than 10 test cases with n > 10.

输出

For each test case, if there exists a plan of allocation meet David's demand, print "YES" (without quotation) in the first line, and in the next line, print a string consisting of English letters "A" and "B". The i-th character is "A" indicates that the i-th colony was allocated to C++ Empire, and "B" indicates the Java Republic.

If there are several possible solutions, you could print just one of them.

If there is no solution, print "NO".

注意

This problem is special judged.

样例输入

2
2
0 0
0 1
4
0 0
0 1
1 0
1 1

样例输出

NO
YES
ABBA

【题意】

给n个点,是否不能用一条直线将这些点分成两部分,若是,则输出YES并输出方案,若不是,则输出NO。

【解题思路】

显然当n<=2时是不能的。

当n=3时,若n个点可构成直线则是可以的,比如ABA,若不能构成直线,则不行。

当n>3时,不管怎样都是可以的,如果围成凸包用了所有点,只需随便挑两个不相邻的点填入A,其余填入B即可。若没有用,只需将凸包上的点填入A,凸包内的点填入B即可。

【代码】

#include<bits/stdc++.h>
using namespace std;
const double PI=acos(1.0);
const int maxn=1005;
int f[maxn];
struct Node
{
    int x,y;
    int num;
}node[maxn],v[maxn];
bool cmp1(Node a,Node b)
{
    return (a.y!=b.y)?a.y<b.y:a.x<b.x;
}
int cross(Node a,Node b,Node c)
{
    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
double dis(Node a,Node b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)*1.0+(a.y-b.y)*(a.y-b.y)*0.1);
}
bool cmp2(Node a,Node b)
{
    int m=cross(node[1],a,b);
    if(m>0)return 1;
    else if(m==0 && dis(node[1],a)-dis(node[1],b)<=0)return 1;
    else return 0;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,x,y;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&x,&y);
            node[i].x=x;node[i].y=y;
            node[i].num=i;
        }
        memset(v,0,sizeof(v));
        memset(f,0,sizeof(f));
        sort(node+1,node+n+1,cmp1);
        v[1]=node[1];
        sort(node+2,node+n+1,cmp2);
        v[2]=node[2];
        int top=2;
        for(int i=3;i<=n;i++)
        {
            while(top>1 && cross(v[top-1],v[top],node[i])<=0)
                top--;
            v[++top]=node[i];
        }
        //printf("%d\n",top);
        if((n==3 && top==3) || n<=2)
        {
            printf("NO\n");
            continue;
        }
        if(top==n)f[v[1].num]=1,f[v[3].num]=1;
        else
        {
            for(int i=1;i<=top;i++)
            {
                f[v[i].num]=1;
            }
        }
        printf("YES\n");
        for(int i=1;i<=n;i++)
        {
            if(f[i])printf("A");
            else printf("B");
        }
        printf("\n");
    }

}

猜你喜欢

转载自blog.csdn.net/qq_39826163/article/details/83862822