ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 E.Territorial Dispute

来源:互联网 发布:淘宝店托管 编辑:程序博客网 时间:2024/05/01 19:20

题目链接:https://hihocoder.com/problemset/problem/1582

题目大意:问是否存在方案,使两个王国的城市不能分布在边界的两侧

解题思路:当n=3时的一个trick是共线的时候是存在方案的,当n>3时,当一个王国连成的城市把另一个王国全部包进去的时候,一定不能被划分开,所以想到用凸包,但是凸包可能不存在在内部的点,那么就可以把凸包边界上的点隔一个标记为一个城市,那么同一个城市必然不能被分在两块

AC代码:

#include<cstdio>#include<cmath>#include<iostream>#include<algorithm>#include<iomanip>#include<vector>using namespace std;const int MAXN = 200000 + 5;int stack[MAXN], top;char ans[MAXN];struct Point{    int _x, _y, _numb;    Point(int x = 0, int y = 0,int numb=0) :_x(x), _y(y),_numb(numb) {}    Point operator-(Point a) { return Point(_x - a._x, _y - a._y); }}polygon[MAXN];int getDis(Point a, Point b){    return (a._x - b._x)*(a._x - b._x) + (a._y - b._y)*(a._y - b._y);}int getCross(Point p1, Point p2, Point p){    return (p1._x - p._x)*(p2._y - p._y) - (p2._x - p._x)*(p1._y - p._y);}bool myCmp(Point a, Point b){    int flag = getCross(a, b, polygon[0]);    if (flag > 0) return true;    if (flag == 0 && getDis(a, polygon[0]) < getDis(b, polygon[0]))        return true;    return false;}int toGraham(Point polygon[],int n){    if (n == 1)    {        stack[0] = 0;        return 1;    }    int pos = 0;    for (int i = 1;i < n;++i)    {        if (polygon[pos]._y > polygon[i]._y)            pos = i;        else if (polygon[pos]._y == polygon[i]._y&&polygon[pos]._x > polygon[i]._x)            pos = i;    }    swap(polygon[0], polygon[pos]);    sort(polygon + 1, polygon + n, myCmp);    int top = 2;    stack[0] = 0, stack[1] = 1;    for (int i = 2;i < n;i++)    {        while (top>1&&getCross(polygon[i], polygon[stack[top - 2]], polygon[stack[top - 1]]) < 0) top--;        stack[top++] = i;    }    return top;}int main(){    int t;scanf("%d", &t);    while (t--)    {        int n;scanf("%d", &n);        for (int i = 0;i < n;++i)        {            scanf("%d%d", &polygon[i]._x, &polygon[i]._y);            polygon[i]._numb = i;            ans[i] = '0';        }        if (n <= 2|| n == 3 && getCross(polygon[0], polygon[1], polygon[2])!=0)        {            puts("NO");            continue;        }        puts("YES");        int tot = toGraham(polygon, n);        if (tot < n)            for (int i = 0;i < tot;i++)                ans[polygon[stack[i]]._numb] = 'A';        else            for (int i = 0;i < tot;i++)                if(i%2)                     ans[polygon[stack[i]]._numb] = 'A';        for (int i = 0;i < n;i++)        {            if (ans[i] == 'A') putchar(ans[i]);            else putchar('B');        }        puts("");       }    return 0;}
阅读全文
0 0