HDU 5754 Life Winner Bo (找规律and博弈)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5754
给你四种棋子,棋子一开始在(1,1)点,两个人B和G轮流按每种棋子的规则挪动棋子,棋子只能往右下方移动,谁最后先挪动棋子到(n,m)位置,谁就胜利。要是两个人都不可能赢,就输出D。
king的情况在纸上模拟了一下,感觉就是当n*m为奇数时先手输,否则就赢。
rook的情况比较简单,相当于在两堆石子中取石子,只能在一堆中取。当n等于m时,先手必败,因为先手怎么取,后手都会跟上取 使得两堆石子相同。
knight的情况也是在纸上模拟了一下,发现4*4 7*7 10*10...这些情况先手都是输,因为先手无论怎走,后手都会调整方向,所以(n == m && (n - 1) % 3 == 0)时,先手输。
还有2*3 5*6 8*9...都是先手赢。其余都是平局。
queen的情况,比赛的时候没发现,原来是威佐夫博弈,问题可以转化为两堆石子,可以从中一堆取,或者从两堆中取同样的数目。具体可以百度一下,套个公式就可以了,注意n和m要减1。
1 //#pragma comment(linker, "/STACK:102400000, 102400000") 2 #include <algorithm> 3 #include <iostream> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cstdio> 7 #include <vector> 8 #include <cmath> 9 #include <ctime> 10 #include <list> 11 #include <set> 12 #include <map> 13 using namespace std; 14 typedef long long LL; 15 typedef pair <int, int> P; 16 const int N = 1e5 + 5; 17 18 void king(int n, int m) { 19 if((n * m) % 2) 20 printf("G\n"); 21 else 22 printf("B\n"); 23 } 24 25 void rook(int n, int m) { 26 if(n == m) 27 printf("G\n"); 28 else 29 printf("B\n"); 30 } 31 32 void knight(int n, int m) { 33 if(n < m) 34 swap(n , m); 35 if(n == m && (n - 1) % 3 == 0) 36 printf("G\n"); 37 else if(n - m == 1 && n % 3 == 0) 38 printf("B\n"); 39 else 40 printf("D\n"); 41 } 42 43 void queen(int n, int m) { 44 n-- , m--; 45 double x = (1 + sqrt(5.0))/2.0; 46 if(n < m) 47 swap(n , m); 48 if(m == int((n - m)*x)) 49 printf("G\n"); 50 else 51 printf("B\n"); 52 } 53 54 int main() 55 { 56 int t , n , m , c; 57 scanf("%d" , &t); 58 while(t--) { 59 scanf("%d %d %d" , &c , &n , &m); 60 if(c == 1) { 61 king(n , m); 62 } 63 else if(c == 2) { 64 rook(n , m); 65 } 66 else if(c == 3) { 67 knight(n , m); 68 } 69 else { 70 queen(n , m); 71 } 72 } 73 return 0; 74 }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步