2020杭电多校第七场 Game(博弈)

Problem Description
Notice:Don’t output extra spaces at the end of one line.

Dodo bird and ddd are playing a stone game on a 2-d plane. There are n points on the plane where they can put the stone. The rule is as follows:

  • Before the game start, The stone is at the first point.
  • Dodo and ddd move the stone in turn, Dodo moves first.
  • In the first move, the player can move the stone to any point except the first point.
  • Starting from the second move, assume the stone is currently at point x, and the distance of the stone traveled in the last move is d. The player can move the stone to a point y if and only if distance(x,y)>d and point y has never been visited before.
  • If a player cannot make a move, he loses the game.

Please determine who will win the game if both player use the best strategy.

Input
The first line contains an integer T(1≤T≤100), indicating the number of test cases.

Each test case contains several lines. The first line contains an integer n(2≤n≤2000), indicating the number of points. Next n lines, each line contains two integers xi,yi(−109≤x,y≤109), indicating the coordinate of the i-th point.

It is guaranteed that there are at most 12 test cases with n>500.

Output
For each test case, If Dodo can win the game, print “YES”. Otherwise, print “NO”.

Sample Input
2
5
1 1
0 0
2 0
0 2
2 2
4
1 1
0 0
0 2
2 2

Sample Output
NO
YES

Source
2020 Multi-University Training Contest 7

题意:
A,B轮流走,要求每次走的欧几里得距离比上一次大。且走过的点不能再走,不能走的人输了,问先手是否必胜。

思路:
必胜点意味着能走到一个必败点。
必败点意味着不能再走或者所有能走的点都是必胜点。

考虑最远距离的点对,这些点之间肯定互为必胜点,谁先走到这些点中行动,下一个人就不能再行动了。

所以拆掉这些点再考虑剩下点中的最远点对,也是同样的考虑。不妨叫做次远点对,则谁先在这些次远点对中行动,下一步那个人就只能走到最远点对了,所以次远点对还是必胜点。

可以判断出,最后最多只剩下一个必胜点(所以偶数必胜)。

如果最后只剩下一个点且为点1,意味着1对应的所有点都是必胜点,所以1必败,否则肯定能走到一个必败点或者本身就是必胜点。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <iostream>
#include <map>
#include <string>
#include <set>

using namespace std;

typedef long long ll;

const int mod = 1e9 + 7;
const int maxn = 2e3 + 7;

struct Node {
    int x,y;
    ll d;
}a[maxn],p[maxn * maxn];

int vis[maxn];

int cmp(Node x,Node y) {
    return x.d < y.d;
}

ll dis(int i,int j) {
    return 1ll * (a[i].x - a[j].x) * (a[i].x - a[j].x) + 1ll * (a[i].y - a[j].y) * (a[i].y - a[j].y);
}

int main() {
    int T;scanf("%d",&T);
    while(T--) {
        int n;scanf("%d",&n);
        for(int i = 1;i <= n;i++) {
            scanf("%d%d",&a[i].x,&a[i].y);
            vis[i] = 0;
        }
        int cnt = 0;
        for(int i = 1;i <= n;i++) {
            for(int j = i + 1;j <= n;j++) {
                p[++cnt] = {i,j,dis(i,j)};
            }
        }
        sort(p + 1,p + 1 + cnt,cmp);
        int num = n;
        for(int i = cnt;i >= 1;i--) {
            int x = p[i].x,y = p[i].y;
            if(!vis[x] && !vis[y]) {
                num -= 2;
                vis[x] = 1;
                vis[y] = 1;
            }
        }
        if(num == 0) {
            printf("YES\n");
        } else if(num == 1 && vis[1]) {
            printf("YES\n");
        } else {
            printf("NO\n");
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值