[BZOJ3298: [USACO 2011Open]cow checkers]威佐夫博弈
只能背结论的渣渣
第2行:一个整数T;
第3到第T+2行:两个用空格隔开的整数x和y.
3298: [USACO 2011Open]cow checkers
Time Limit: 10 Sec Memory Limit: 128 MB Submit: 199 Solved: 100 [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
第1行:两个用空格隔开的整数M和N;第2行:一个整数T;
第3到第T+2行:两个用空格隔开的整数x和y.
Output
第1到T行:包含“Farmer John”或者是“Bessie”,表示谁赢了这轮游戏。Sample Input
3 3 1 1 1Sample Output
BessieHINT
Source
Silver 根据威佐夫博弈的结论,对于可以在一堆中选若干个,或者在两堆中拿相同个数个,最后无后续状态者输,结论:两堆x,y(x<y),先手输当且仅当$ (y-x)*\frac{\sqrt{5}+1}{2} == x $,不要问我这个结论哪里来的orz orz orz#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
int n,m;
int main() {
scanf("%d%d",&m,&n);
int t;
scanf("%d",&t);
while(t--) {
int x,y;
scanf("%d%d",&x,&y);
if(x>y) swap(x,y);
int k = (y-x);
int o = (k*(1.0+sqrt(5))/2.0);
if(o==x) puts("Farmer John");
else puts("Bessie");
}
}