【博弈+GCD】C. Alice and Bob
https://www.bnuoj.com/v3/contest_show.php?cid=9147#problem/C
【题意】
初始时有n个数,定义操作为从n个数中取出两个数x,y,如果|x-y|不在set中,操作就是合法的,并且把|x-y|加到set里。最后不能操作的人输。A和B轮流操作,A先手,问最后谁赢。
【思路】
通过观察发现6,8,10和3,4,5的情况其实是一样的,不同的是前者的每个数都是后者的2倍。所以可以想到与GCD有关,而且GCD本身也是辗转相减。所以就想到了GCD。最后很容易想到是简化成互质数后的max-n.
【Accepted】
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 int n; 7 const int maxn=1e2+10; 8 const int inf=0x3f3f3f3f; 9 int a[maxn]; 10 typedef long long ll; 11 12 int GCD(int a,int b) 13 { 14 return b==0?a:GCD(b,a%b); 15 } 16 int main() 17 { 18 while(~scanf("%d",&n)) 19 { 20 int mmax=-inf; 21 for(int i=0;i<n;i++) 22 { 23 scanf("%d",&a[i]); 24 mmax=max(mmax,a[i]); 25 } 26 sort(a,a+n); 27 int gcd=GCD(a[0],a[1]); 28 for(int i=2;i<n;i++) 29 { 30 gcd=GCD(gcd,a[i]); 31 } 32 int ans=mmax/gcd-n; 33 if(ans%2==0) 34 { 35 puts("Bob"); 36 } 37 else 38 { 39 puts("Alice"); 40 } 41 } 42 return 0; 43 }