首页 > 代码库 > bzoj 3298: [USACO 2011Open]cow checkers -- 数学

bzoj 3298: [USACO 2011Open]cow checkers -- 数学

3298: [USACO 2011Open]cow checkers

Time Limit: 10 Sec  Memory Limit: 128 MB

Description

   一天,Besssie准备和FJ挑战奶牛跳棋游戏。这个游戏上在一个M*N(1<=M<=1,000,000;1<=N<=1,000,000)的棋盘上, 
这个棋盘上在(x,y)(0<=x棋盘的左下角是(0,0)坐标,棋盘的右上角是坐标(M-1,N-1)。 
Bessie每次都是第一个移动棋子,然后Bessie与Fj轮流移动。每一轮可以做以下三种中的一种操作:  
1)在同一行,将棋子从当前位置向左移动任意格; 
2)在同一列,将棋子从当前位置向下移动任意格;  
3)将棋子从当前位置向下移动k格再向左移动k格(k为正整数,且要满足移动后的棋子仍然在棋盘上)  


第一个不能在棋盘上移动的人比赛算输(因为棋子处在(0,0)点)。 
共有T个回合(1<=T<=1,000),每次给出一个新起始点的坐标(x,y),确定是谁赢。 

 

Input

第1行:两个用空格隔开的整数M和N;  
第2行:一个整数T;  
第3到第T+2行:两个用空格隔开的整数x和y. 

 

Output

 

第1到T行:包含“Farmer John”或者是“Bessie”,表示谁赢了这轮游戏。

 

 

 

Sample Input

3 3
1
1 1

Sample Output


Bessie

HINT

分析必败点,可以发现,必败点的同一行,同一列,同一对角线上的点都是必胜点

所以可知,每一列都只有一个点,并且这些点沿对角线对称

然后就可以O(n) 递推求出每一列的必败点,然后直接回答即可

#include<map>#include<cmath>#include<queue>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define inf 1000000007#define ll long long#define N 1000000inline int rd(){    int x=0,f=1;char ch=getchar();    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}    return x*f;}int a[N+10],n,m,T;int main(){    a[1]=1;int tp=1;    for(int i=1;i<=N;i++)    {        if(a[i]) continue;        a[i]=a[tp]+i-tp+1;tp=i;        if(a[i]<=N) a[a[i]]=i;    }    n=rd();m=rd();T=rd();    int x,y;    while(T--)    {        x=rd()+1;y=rd()+1;        if(a[x]==y||a[y]==x) puts("Farmer John");        else puts("Bessie");    }    return 0;}

 

bzoj 3298: [USACO 2011Open]cow checkers -- 数学