zoukankan      html  css  js  c++  java
  • Game【博弈论】-2020杭电多校7

    题意

    在二维平面上给出 (n) 个点的坐标,初始时刻,有一颗石头在第一个点,两个人轮流移动石头,要求当前移动的距离要比上一次的移动距离大,并且一个点只能用一次。不能移动的人输。问先手胜还是后手胜。

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6850

    分析

    本题关键在于如何确定必胜的策略,可以发现,当一个人选择的是最长边的一个端点,那么另一个人只要选择另一个端点,就可以获胜。如果把最长边依次选取出来,如果最后只剩下起点 (1) 一个点,那么不管先手选择哪一个点,后手总可以选择该点所在边的另一个点,使得先手输,否则先手必胜。

    代码

    
    #include <bits/stdc++.h>
    #define pb push_back
    using namespace std;
    typedef long long ll;
    const int N=2005;
    int x[N],y[N];
    struct node
    {
        ll dis;
        int a,b;
        bool operator < (const node d)const
        {
            return dis>d.dis;
        }
    };
    vector<node>point;
    set<int>st;
    bool vis[N];
    int main()
    {
        int T,n;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            point.clear();
            for(int i=1;i<=n;i++) vis[i]=0;
            for(int i=1;i<=n;i++)
                scanf("%d%d",&x[i],&y[i]);
            for(int i=1;i<n;i++)
            {
                for(int j=i+1;j<=n;j++)
                {
                    ll d=1LL*(x[i]-x[j])*(x[i]-x[j])+1LL*(y[i]-y[j])*(y[i]-y[j]);
                    point.pb(node{d,i,j});
                }
            }
            sort(point.begin(),point.end());
            int f=0,sum=n;
            for(int i=0;i<point.size();i++)
            {
                if(vis[point[i].a]||vis[point[i].b]) continue;
                ll td=point[i].dis;
                st.clear();
                int j=i;
                while(j<point.size()&&point[j].dis==td)
                {
                    if(vis[point[j].a]||vis[point[j].b])
                    {
                        j++;
                        continue;
                    }
                    st.insert(point[j].a);
                    st.insert(point[j].b);
                    j++;
                }
                i=j-1;
                set<int>::iterator it;
                for(it=st.begin();it!=st.end();it++)
                    vis[*it]=1;
                if(vis[1]&&sum>1)
                {
                    f=1;
                    break;
                }
                sum-=st.size();
            }
            if(f) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
    
    
  • 相关阅读:
    Spring Boot SockJS应用例子
    Spring Boot+STOMP解决消息乱序问题
    Spring boot集成Websocket,前端监听心跳实现
    吐槽Windows 8,就没见过这么烂的平板操作系统
    怎样在MyEclipse上耍Chrome
    HDOJ 4876 ZCC loves cards
    IIS7.5 配置 PHP 5.3.5
    关于ANDROID模拟器的一些事
    性能測试命令字段解释
    排序算法复习
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/13489029.html
Copyright © 2011-2022 走看看