链接:http://acm.hdu.edu.cn/showproblem.php?pid=3544
给一块n*m的巧克力,Alice只能竖切切成A*m和B*m,且(A+B=n),Bob只能竖切成n*A和n*B,qie(A+B=m)(谁不能进行操作就算输)
后者会尽量选前着切后其中小的一块来切,那么先手须尽量取中间来切。
设切割对Alice的贡献值为正,对Bob的贡献值为负;
分情况讨论:
1,若只有n*1对Alice有利,仅有1*m对Bob有利。
2,若2*2的巧克力(这是个bug,谁也不愿意去切)(谁先切就等于白给对方两次机会,(你品,你细品)
3,2*3,3*2同理要被抛弃;
4,若n*2,Alice肯定想尽办法多切几刀,Bob不会去切(注意,不能切1*2这样对Bob有利,则每次都切2*2,次数有(n/2)-1),2*m反之;
5,则n*3,3*m,......都一样
代码:
#include<bits/stdc++.h>
#define ll long long
const int maxn=200020;
const int inf=-0x3f3f3f;
using namespace std;
ll gcd(int a,int b){return b==0?a:gcd(b,a%b);}
ll lcm(int a,int b){return gcd(a,b)/a*b;}
int fa1[maxn],fa2[maxn];
int n1,m1,n2,m2;
void solve(int k)
{
int n;
scanf("%d",&n);
ll a=0,b=0;
for(int i=1; i<=n; i++)
{
ll x,y;
scanf("%lld%lld",&x,&y);
while(x>1&&y>1) //让其变成4的那种形式
{x>>=1; y>>=1;}
if(y==1) a+=x-1;//能切x-1刀
if(x==1) b-=y-1;//能切y-1刀
}
printf("Case %d: %s
", k, a+b>0? "Alice" : "Bob");
return ;
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1; i<=t; i++)
solve(i);
return 0;}