hdu5754_找规律+威佐夫博弈
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5754
题意:
t组数据, 每组数据三个数,c, n, m; c代表哪一种棋子,1是国王,2是车,3是马, 4是皇后,n 和m表示棋盘的大小
B和G两个人从(1, 1)开始, 谁先到(n, m)谁就赢,两个人都很smart
国王:2 * x的情况下,先手掌握了先机,(1, 1) --> (2, 1)或者(2, 2), 后手都只能向右走。。。
车:在n * n的点先手是必输态
马:(x, y) --> (x+1, y+2) (a)
(x, y) --> (x+2, y+1) (b)
如果a和b的步数相等,肯定是后手赢,因为后手可以根据先手的走法选择a还是b(先手a后手b, 先手b后手a)
如果a和b的步数相差1,肯定是先手赢,先手先选多1的那个走法,然后情况就变成了同上
其他情况就是平局了
皇后:
威佐夫博弈,把x轴要走的步数当成一堆石子, y轴要走的步数当成另一堆石子(注意是n-1, m-1)
有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜。
公式如下
ai=[i*(1+√5)/2](方括表示下取整)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <algorithm> 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <vector> 7 #include <cmath> 8 #include <ctime> 9 #include <list> 10 #include <set> 11 #include <map> 12 using namespace std; 13 14 void King(int n , int m) { 15 if(n % 2 == 1 && m % 2 == 1) 16 printf("G\n"); 17 else 18 printf("B\n"); 19 } 20 void Rook(int n , int m) { 21 if(n == m) 22 printf("G\n"); 23 else 24 printf("B\n"); 25 } 26 void Queen(int n , int m) { 27 n--, m--; 28 if(n < m) 29 swap(n, m); 30 int t = n - m; 31 n = (int)(t * (1.0 + sqrt(5.0))/2.0); 32 if(n == m) 33 printf("G\n"); 34 else 35 printf("B\n"); 36 } 37 38 void Knight(int n , int m) { 39 if(n == m && (n - 1) % 3 == 0 && (m - 1) % 3 == 0) 40 printf("G\n"); 41 else if(n - 2 == m - 1 && (n - 3) % 3 == 0 && (m - 2) % 3 == 0) 42 printf("B\n"); 43 else if(n - 1 == m - 2 && (n - 2) % 3 == 0 && (m - 3) % 3 == 0) 44 printf("B\n"); 45 else 46 printf("D\n"); 47 } 48 49 int main() 50 { 51 int t , n , m , c; 52 scanf("%d" , &t); 53 while(t--) { 54 scanf("%d %d %d" , &c , &n , &m); 55 if(c == 1) { 56 King(n , m); 57 } 58 else if(c == 2) { 59 Rook(n , m); 60 } 61 else if(c == 3) { 62 Knight(n , m); 63 } 64 else { 65 Queen(n , m); 66 } 67 } 68 return 0; 69 }