CF Gym 102059I Game on Plane(sg函式)
You are givenNNpoints on a plane. These points are precisely the set of vertices of some regularNN-gon. Koosaga, an extreme villain, is challenging you with a game using these points. You and Koosaga alternatively take turns, and in each turn, the player
- chooses two of the given points, then
- draws the line segment connecting the two chosen points.
Given the integer
The input consists of many test cases. The first line contains an integerTT(1≤T≤50001≤T≤5000), the number of test cases. Each of the following
For each test case, print one line containing the stringFirstif you need to move first orSecondif you need to move second so that you can win regardless of Koosaga's moves.
Example input Copy2output Copy
3
5
First
Second
題目描述:給n個點,每次可以選2個點連線,連線的線不能相交,不能連線的輸。
思路:考慮兩個點連線,把一堆點分成兩堆,可以轉換成分成2個子遊戲,原來的遊戲的sg值就是子游戲的sg值xor和。
假設是點a和點b連成的線把原遊戲劃分成2個子遊戲,因為如果我從子游戲中找任意一點x和a相連,對手總能讓x與b相連,不改變勝負結果。所以用來劃分的點可以直接丟掉。即遊戲n分成i和n-i-2的子游戲,跑一次sg函式。
程式碼:
#include<bits/stdc++.h> #define sd(x) scanf("%d",&x) #define lsd(x) scanf("%lld",&x) #define ms(x,y) memset(x,y,sizeof x) #define fu(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) #define all(a) a.begin(),a.end() using namespace std; using namespace __gnu_cxx; typedef long long ll; typedef unsigned long long ull; typedef long double ld; typedef pair<int,int> P; const int N=1e4+99; const ll mod=2147493647; const int INF=1e9+7; int sg[N]; int Sg(int n) { if(sg[n]!=-1) return sg[n]; set<int> s;s.clear(); for(int i=0;i<=n&&n-i-2>=0;i++) { s.insert(Sg(i)^Sg(n-i-2)); } int res=0; while(s.count(res)) res++; return sg[n]=res; } int main() { int t;sd(t); ms(sg,-1); sg[0]=0; while(t--) { int n;sd(n); if(Sg(n)!=0) puts("First"); else puts("Second"); } return 0; }