【2016杭电女生赛1007】【博弈 打表找规律】Alice and Bob 可走k步斜对角线的胜负态

来源:互联网 发布:top域名表示什么意思 编辑:程序博客网 时间:2024/04/29 07:34
#include<stdio.h> #include<iostream>#include<string.h>#include<string>#include<ctype.h>#include<math.h>#include<set>#include<map>#include<vector>#include<queue>#include<bitset>#include<algorithm>#include<time.h>using namespace std;void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }#define MS(x,y) memset(x,y,sizeof(x))#define MC(x,y) memcpy(x,y,sizeof(x))#define MP(x,y) make_pair(x,y)#define ls o<<1#define rs o<<1|1typedef long long LL;typedef unsigned long long UL;typedef unsigned int UI;template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }const int N = 0, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;int casenum, casei;int Q, K, n, m;int f[100][100];int dp(int n, int m){if (n == 1 && m == 1)return 0;if (~f[n][m])return f[n][m];if (n > 1 && !dp(n - 1, m))return f[n][m] = 1;if (m > 1 && !dp(n, m - 1))return f[n][m] = 1;if (n > K&&m > K&&!dp(n - K, m - K))return f[n][m] = 1;return f[n][m] = 0;}void table(int k){K = k;for (n = 1; n <= 20; ++n){for (m = 1; m <= 20; ++m){MS(f, -1);printf("%d ", dp(n, m));}puts("");}}int main(){//table(1);table(2);table(3);scanf("%d", &casenum);for (casei = 1; casei <= casenum; ++casei){scanf("%d%d", &Q, &K); ++K; //首先先使得K+=1while (Q--){scanf("%d%d", &n, &m);//规律1:如果较小宽度为K的倍数,那么先手必胜if (n > m)swap(n, m); //n<=mif (n%K == 0){puts("Alice");continue;}//规律2:距离顶角元素距离的奇偶性,一样对答案有所影响(特判K==2)int len = n / K;if (K > 2 && (len & 1)){puts((n + m) % 2 == 0 ? "Alice" : "Bob");}else{puts((n + m) % 2 == 0 ? "Bob" : "Alice");}}}return 0;}/*【trick&&吐槽】判定奇偶性的时候——%2==1往往是错的,有时%2==-1。还是&1 来判定奇偶性的方法比较靠谱【题意】给你一个棋盘,大小为n*m。我们一开始在(1,1)点,如果我们当前在(x,y),那么我们可以在一步之内走到(x+1,y)(x,y+1)(x+k,y+k)先告诉你k,k∈[1,1e9]然后有q组询问,q∈[1,1000]对于每个q,告诉你(n,m)n∈[1,1e9],m∈[1,1e9]。无法可走便输了,问先手必胜还是后手必胜。【类型】博弈 打表找规律【分析】对于这题,n和m都是1e9,太大了。于是我们要考虑O(1)出解。即打表找规律。至于,什么是打表找规律呢?1,问题数据规模很小,我们可以本地预处理出所有解,然后存到代表段数组中,O(1)输出2,问题数据规模很大,我们可以本地跑出小数据的答案,然后猜解大数据的规律。对于这题——K==1时,表示这样的:0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 10 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 10 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 10 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 10 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 10 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 10 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 10 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 10 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 10 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1K==2时,表示这样的:0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 11 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 00 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 10 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 01 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 10 1 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 11 0 1 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 00 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 11 0 1 1 0 1 1 0 1 1 0 1 0 1 0 1 0 1 0 10 1 1 0 1 1 0 1 1 0 1 0 1 0 1 0 1 0 1 01 0 1 1 0 1 1 0 1 1 0 1 1 1 1 1 1 1 1 10 1 1 0 1 1 0 1 1 0 1 1 0 1 0 1 0 1 0 11 0 1 1 0 1 1 0 1 1 0 1 1 0 1 0 1 0 1 00 1 1 0 1 1 0 1 1 0 1 1 0 1 1 1 1 1 1 11 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 0 10 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 0 1 01 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 10 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 11 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0K==3时,表示这样的:0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 11 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 00 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 11 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 10 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 01 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 10 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 01 0 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 10 1 0 1 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 11 0 1 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 00 1 0 1 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 11 0 1 1 0 1 0 1 1 0 1 1 1 1 1 1 1 1 1 10 1 0 1 1 0 1 1 0 1 0 1 1 0 1 0 1 0 1 01 0 1 1 0 1 0 1 1 0 1 1 0 1 0 1 0 1 0 10 1 0 1 1 0 1 1 0 1 0 1 1 0 1 0 1 0 1 01 0 1 1 0 1 0 1 1 0 1 1 0 1 0 1 1 1 1 10 1 0 1 1 0 1 1 0 1 0 1 1 0 1 1 0 1 0 11 0 1 1 0 1 0 1 1 0 1 1 0 1 0 1 1 0 1 00 1 0 1 1 0 1 1 0 1 0 1 1 0 1 1 0 1 0 11 0 1 1 0 1 0 1 1 0 1 1 0 1 0 1 1 0 1 1我们发现到,对于K>1时,对于f[K][K]~f[K][∞],答案都是1(先手必胜)对于f[K][K]~f[∞][K],答案都是1(先手必胜)对于f[2K][2K]~f[2K][∞],答案都是1(先手必胜)对于f[2K][2K]~f[∞][2K],答案都是1(先手必胜)对于f[3K][3K]~f[3K][∞],答案都是1(先手必胜)对于f[3K][3K]~f[∞][3K],答案都是1(先手必胜)......即f[nK][nK]~f[nK][∞],答案都是1(先手必胜)  f[nK][∞]~f[nK][nK],答案都是1(先手必胜)对于其它的f(i,j),我们要找到第一个位置(pK,pK),满足i>=pK且j>=pK。然后:如果p是奇数,那么与(pK,pK)同奇偶性的(即横纵坐标之和同奇偶性)都是必胜点,否则为必败点如果p是偶数,那么与(pK,pK)同奇偶性的(即横纵坐标之和同奇偶性)都是必败点,否则为必胜点然而,对于K==1的时候,是特例的。不论p是奇数还是偶数,与(pK,pK)同奇偶性的(即横纵坐标之和同奇偶性)都是必败点,否则为必胜点这里再尝试一下证明:(我们不妨把题目中的由从(1,1)->(n,m)),改变方向为从(n,m)走到(1,1),这样答案不变,然而考虑和看起来更直观。对于初始K==1的,对于(n,m)==(X,X),初始点(先手)的胜负态为:(1,1):必败态(1,x)为(1,x-1)的反态,(x,1)为(x-1,1)的反态,为必胜态和必败态的依次轮转。(2,2):必胜态(2,x)和(x,2):都可以找到(1,x)和(1,x-1)的两个前驱,必然有必败态的前驱,所以全为必胜态接下来所有点都找不到任何一个必败态的前驱,其状态又归回于——(3,3):必败态(3,x)为(3,x-1)的反态,(x,3)为(x-1,3)的反态,为必胜态和必败态的依次轮转。(4,4):必胜态(4,x)都可以找到(3,x)和(3,x-1)的两个前驱,(4,x)都可以找到(3,x)和(3,x-1)的两个前驱,必然有必败态的前驱,所以全为必胜态……所以我们对K==1条件下的结论是正确的对于初始K>1的,我们不妨使得K+=1,然后,对于(n,m)==(X,X),初始点(先手)的胜负态为:(1~K-1,x)与(x,1~K-1),这些点都是不涉及到斜着走K步的情况的,于是胜负只与奇偶性有关,即偶点必败奇点必胜。(K,K):必胜态,因为其可以一步到(1,1)这个必败态。(K,K~x)和(K~x,K),其既可以达到奇点,又可以达到偶点,所以是必胜态。就是按照这个过程,奇偶归类,虽然很繁琐,然而我们可以得到结论的证明>_<*/

0 0
原创粉丝点击