您的位置:首页 > 其它

HDU 5754 博弈(威佐夫博弈)

2016-07-26 20:22 246 查看
这个题除了皇后的可以套用一下威佐夫博弈以外其他的都可以找规律找出来,主要为了学习一下威佐夫博弈,

威佐夫博弈:给两堆石子,每次都可以从其中一堆石子中取n个石子或者从两堆石子中都取n个石子,最后将石子取完的获胜。

解是根据:

int k = abs(n - m);
n = (int)((double)k * (1.0 + sqrt(5.0)) / 2.0);
if (n == m) printf("G\n");
else printf("B\n");


来判断谁获胜的,但是这个题可能是因为精度问题,用这个直接判断AC不了。=.=

也可以根据规律来打个威佐夫博弈的表

int x = 1, y = 1;
for(int i = 1; ; ++i) {
int add = 1;
while(vis[x + add] || vis[y + 1 + add]) add++;
x += add, y += add + 1;
if(x >= maxn || y >= maxn) break;
vis[x] = vis[y] = true;
matc[x][y] = true;
matc[y][x] = true;
}


AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <cstdlib>
#include <queue>
using namespace std;

const int eps = 1e-6;
const int maxn = 1200 + 50;

int s[maxn][maxn];
int T;
int n,m;

int knight(int x,int y) {
if(x == y && (x - 1) % 3 == 0) return 0;
else if((x + 1 == y + 2) && (x % 3 == 0)) return 1;
else if((y + 1 == x + 2) && (y % 3 == 0)) return 1;
return -1;
}

bool matc[maxn][maxn];
bool vis[maxn];

int main() {

int x = 1, y = 1; for(int i = 1; ; ++i) { int add = 1; while(vis[x + add] || vis[y + 1 + add]) add++; x += add, y += add + 1; if(x >= maxn || y >= maxn) break; vis[x] = vis[y] = true; matc[x][y] = true; matc[y][x] = true; }

scanf("%d",&T);
while(T--) {
int t;
scanf("%d%d%d",&t,&n,&m);
if (t == 4) {
if (matc
[m]) printf("G\n");
else printf("B\n");

// int k = abs(n - m);
// n = (int)((double)k * (1.0 + sqrt(5.0)) / 2.0);
// if (n == m) printf("G\n");
// else printf("B\n");

} else if (t == 2) {
if (n == m) printf("G\n");
else printf("B\n");
} else if (t == 1) {
if ((n & 1) && (m & 1)) printf("G\n");
else printf("B\n");
} else {
int t = knight(n, m);
if (t == -1) printf("D\n");
else if (t == 1) printf("B\n");
else printf("G\n");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  思路