• 2020杭电多校第7场 1007 Game


    原题链接
    题意:
    有一个二维平面,上面有n个点,在第一个点上有一颗石头。现在有两个人做游戏,他们轮流移动石头,
    第一次移动的时候可以将石头移动到平面上的其他任何的点上。之后的每次移动,可以将石头移动到比上次移动距离更远的点上。
    当轮到某人时,他无法再移动石头,则判他为输。

    做法:
    我们先考虑第一步:当前是第一个点,如果说第一个点和其他的某个点是平面中最长距离的点对,则先手必胜。
    同样:也就是说,如果当前点在目前平面上和其他某个点能组成为最长点对的话,当前这个人必胜。
    那么我们可以反着处理一下,在计算所有点对之间的距离后,按照距离从大到小排序之后遍历所有点对,如果我们在遍历点对的途中,
    发现点1已经被遍历过了并且剩下的点的个数大于1,则先手必胜,否则必败。

    #include <bits/stdc++.h>
    #define DEBUG
    #define d1(x) std::cout << #x " = " << (x) << std::endl
    #define d2(x, y) std::cout << #x " = " << (x) << " ," #y " = " << (y) << std::endl
    #define disp(arry, fr, to) 
        { 
            std::cout << #arry " : "; 
            for(int _i = fr; _i <= to; _i++) std::cout << arry[_i] << " "; 
            std::cout << std::endl; 
        }
    
    #define ed end()
    #define bg begin()
    #define mkp make_pair
    #define pb push_back
    #define v(T) vector<T>
    #define all(x) x.bg,x.ed
    #define newline puts("")
    #define si(x) ((int)x.size())
    #define rep(i,n) for(int i=1;i<=n;++i)
    #define rrep(i,n) for(int i=0;i<n;++i)
    #define srep(i,s,t) for(int i=s;i<=t;++i)
    
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    const int maxn = 5e6+10;
    const int inf = 0x7f7f7f7f;
    const ll inf_ll = 1ll*inf*inf;
    const int Mod = 1e9+7;
    const double eps = 1e-7;
    int n;
    double a[2010],b[2010];
    struct node{
        int x,y;
        double dis;
    }e[maxn];
    double cdis(double x1,double y1,double x2,double y2){
        return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
    }
    bool cmp(node a,node b){return a.dis>b.dis;}
    bool vis[maxn];
    
    int main(){
        // freopen("1.out","w",stdout);
        int T;
        scanf("%d",&T);
        for(int _=1;_<=T;_++)
        {
            scanf("%d",&n);
            rep(i,n){
                scanf("%lf%lf",&a[i],&b[i]);
                vis[i]=0;
            }
            int cnt=0;
            rep(i,n){
                for (int j=i+1;j<=n;j++){
                    double dis=cdis(a[i],b[i],a[j],b[j]);
                    e[++cnt].dis=dis;
                    e[cnt].x=i;
                    e[cnt].y=j;
                }
            }
            sort(e+1,e+cnt+1,cmp);
            // rep(i,cnt){
            //     d2(i,e[i].dis);
            // }
            int flag=0;
            int sum = n;
            rep(i,cnt){
                int x=e[i].x,y=e[i].y;
                if(!vis[x] && !vis[y]){
                    vector<int>G; 
                    int j = i;
                    while(j<=cnt && e[j].dis == e[i].dis){
                        int u=e[j].x,v=e[j].y;
                        if(vis[u] || vis[v]){
                            j++;continue;
                        }
                        G.push_back(u),G.push_back(v),j++;
                    }
                    i=j-1;
                    for (auto v : G){
                        vis[v]=1;
                    }
                    if(vis[1] == 1 && sum > 1) flag=1;
                    sum-=G.size();
                }
                if(flag) break;
            }
            // d1(flag);
            if(flag) puts("YES");
            else puts("NO");
        }
        return 0;
    }
    
    点击展开代码块
    你将不再是道具,而是成为人如其名的人
  • 相关阅读:
    Allegro PCB转换成PADS方法
    Altium Designer只显示某一层,隐藏其他层
    DCDC功率电感(Inductor)选型
    DDR布线教程
    DDR地址、容量计算、Bank理解
    DDR3中的ODT(On-die termination)
    LINUX文件系统操作指令之四
    linux系统之间通过nfs网络文件系统挂载设置方法
    linux消息队列编程实例
    system()函数
  • 原文地址:https://www.cnblogs.com/wsl-lld/p/13540542.html
Copyright © 2020-2023  润新知