BZOJ3298: [USACO 2011Open]cow checkers(佐威夫博弈)
阿新 • • 發佈:2018-12-01
3298: [USACO 2011Open]cow checkers
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 195 Solved: 96
[Submit][Status][Discuss]
Description
一天,Besssie準備和FJ挑戰奶牛跳棋遊戲。這個遊戲上在一個M*N的棋盤上, 這個棋盤上在(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),確定是誰贏。 1<=M<=1,000,000;1<=N<=1,000,000Input
Output
第1到T行:包含“Farmer John”或者是“Bessie”,表示誰贏了這輪遊戲。
Sample Input
3 31
1 1
Sample Output
BessieHINT
Source
思路:開始看到通過的人少,沒想到就是一個裸的博弈。
開始我是這樣想的,對於每一行,每一列,都至多有一個必敗態。我們可以先打表求出早規律。
先有(0,0)為必敗態,然後標記這一行,這一列,以及這個對角線。 然後輸出的就是 (0,0) (2,1)( 5,3) (7,4)....
#include<bits/stdc++.h> using namespace std; const int maxn=1000010; int lose[maxn],x[maxn],y[maxn],d[maxn]; void solve(int N) { y[0]=1; d[0]=1; for(int i=1;i<=N;i++){ for(int j=1;j<i;j++){View Codeif(!y[j]&&!d[i-j]&&!x[j]){ cout<<i<<" "<<j<<endl; x[i]=1; y[j]=1; d[i-j]=1; break; } } } } int main() { int T,N,M,x,y; solve(100); return 0; }
這不就是兩堆石子,可以取任一堆任意個,或者兩堆取一樣多的模型嗎。。。。失了智了。
#include<bits/stdc++.h> using namespace std; int main() { int T,N,M,x,y; scanf("%d%d%d",&N,&M,&T); while(T--){ scanf("%d%d",&x,&y); if(x>y) swap(x,y); int z=y-x; if((int)((double)1.0*z*((double)1.0*(sqrt(5.0)+1)/2))==x) puts("Farmer John"); else puts("Bessie"); } return 0; }