Life Winner Bo

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5754

Description

Bo is a "Life Winner".He likes playing chessboard games with his girlfriend G.

The size of the chessboard is N×M.The top left corner is numbered(1,1) and the lower right corner is numberd (N,M).

For each game,Bo and G take turns moving a chesspiece(Bo first).At first,the chesspiece is located at (1,1).And the winner is the person who first moves the chesspiece to (N,M).At one point,if the chess can't be moved and it isn't located at (N,M),they end in a draw.

In general,the chesspiece can only be moved right or down.Formally,suppose it is located at (x,y),it can be moved to the next point (x′,y′) only if x′≥x and y′≥y.Also it can't be moved to the outside of chessboard.

Besides,There are four kinds of chess(They have movement rules respectively).

1.king.

2.rook(castle).

3.knight.

4.queen.

(The movement rule is as same as the chess.)

For each type of chess,you should find out that who will win the game if they both play in an optimal strategy.

Print the winner's name("B" or "G") or "D" if nobody wins the game.

Input

In the first line,there is a number T as a case number.

In the next T lines,there are three numbers type,N and M.

"type" means the kind of the chess.

T≤1000,2≤N,M≤1000,1≤type≤4

Output

For each question,print the answer.

Sample Input

4

1 5 5

2 5 5

3 5 5

4 5 5

Sample Output

G

G

D

B

Source

2016 Multi-University Training Contest 3

##题意:

给出N*M的棋盘和棋子的类型,两人以最优策略轮流走.
棋子初始时在(1,1), 先走到(N,M)者获胜.(只能往右下角方向移动)
问对于给定的情形先手胜、败、平.


##题解:

对于每个棋盘只有一个棋子,那么直接分析每个位置的必胜/必败态即可,对于最大的棋盘(1000*1000)打一次表即可.
(1000,1000)为必败态,从右下角往左上角逐个分析每点的状态:
可以到必败态的一定是必胜态; 只能到必胜态的一定是必败态.

1. king:可走到周围的8个格子.
当前位置(i,j)的状态由(i+1,j) (i,j+1) (i+1,j+1)确定.
2. rook:可以横着竖着走任意个格子.
简单推理可得只有i==j时必败,其余必胜.
3. knight:走"L"型路线.
当前位置(i,j)的状态由(i+2,j+1) (i+1,j+2)确定.
不同的是,题目要求不能移动且没有到右下角时为平手,那么只有knight可能出现平手,即走到边界时不能再移动.
对于当前位置,如果能走到必败态,那么一定是必胜态;若不能走到必败态,那么如果能走到平局位置,则一定是平局;
4. queen:横竖斜走任意格子.
对于每个必败态,将可到达的横竖斜格子全部置成必胜态.
(下面代码之所以跑了两遍,是因为第一次我把没有置1的位置全部置0,但是没有用这个0的位置去更新其他点,导致WA).
5. 这里提供样例(5*5)的四种棋子在各个位置的必胜必败态(1必胜 0必败 2平手), 供大家调错.
king:
![](http://images2015.cnblogs.com/blog/764119/201607/764119-20160727102555856-2038384557.png)
rook:
![](http://images2015.cnblogs.com/blog/764119/201607/764119-20160727102336278-2140266223.png)
knight:
![](http://images2015.cnblogs.com/blog/764119/201607/764119-20160727102619309-997808078.png)
queen:
![](http://images2015.cnblogs.com/blog/764119/201607/764119-20160727102627075-1220635971.png)


##代码:
``` cpp
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
#define eps 1e-8
#define maxn 1010
#define mod 100000007
#define inf 0x3f3f3f3f
#define IN freopen("in.txt","r",stdin);
using namespace std;

int king[maxn][maxn];

int rook[maxn][maxn];

int knight[maxn][maxn];

int queen[maxn][maxn];

bool is_ok(int x, int y) {

return x>=1 && y>=1 && x<=1000 && y<=1000;

}

int main(int argc, char const *argv[])

{

//IN;

memset(king, -1, sizeof(king));
memset(rook, -1, sizeof(rook));
memset(knight, -1, sizeof(knight));
memset(queen, -1, sizeof(queen));
king[1000][1000] = 0;
rook[1000][1000] = 0;
knight[1000][1000] = 0;
queen[1000][1000] = 0; for(int i=1000; i>=1; i--) {
for(int j=1000; j>=1; j--) {
if(king[i][j] != -1) continue;
if(is_ok(i+1,j) && !king[i+1][j]) {
king[i][j] = 1; continue;
}
if(is_ok(i,j+1) && !king[i][j+1]) {
king[i][j] = 1; continue;
}
if(is_ok(i+1,j+1) && !king[i+1][j+1]) {
king[i][j] = 1; continue;
}
king[i][j] = 0;
}
} for(int i=1000; i>=1; i--) {
for(int j=1000; j>=1; j--) {
if(i==j) rook[i][j] = 0;
else rook[i][j] = 1;
}
} for(int i=1000; i>=1; i--) {
for(int j=1000; j>=1; j--) {
if(knight[i][j] != -1) continue;
if(!is_ok(i+2,j+1) && !is_ok(i+1,j+2)) {
knight[i][j] = 2;
continue;
}
if(is_ok(i+2,j+1) && !knight[i+2][j+1]) {
knight[i][j] = 1; continue;
}
if(is_ok(i+1,j+2) && !knight[i+1][j+2]) {
knight[i][j] = 1; continue;
}
if(is_ok(i+2,j+1) && knight[i+2][j+1]==2) {
knight[i][j] = 2; continue;
}
if(is_ok(i+1,j+2) && knight[i+1][j+2]==2) {
knight[i][j] = 2; continue;
}
knight[i][j] = 0;
}
} for(int i=1000; i>=1; i--) {
for(int j=1000; j>=1; j--) {
if(queen[i][j] != -1) {
if(queen[i][j] == 0) {
for(int k=1; k<=1000; k++) {
if(is_ok(i-k,j-k)) queen[i-k][j-k] = 1;
else break;
}
for(int k=1; k<=1000; k++) {
if(is_ok(i,j-k)) queen[i][j-k] = 1;
else break;
}
for(int k=1; k<=1000; k++) {
if(is_ok(i-k,j)) queen[i-k][j] = 1;
else break;
}
}
continue;
}
queen[i][j] = 0;
}
} for(int i=1000; i>=1; i--) {
for(int j=1000; j>=1; j--) {
if(queen[i][j] != -1) {
if(queen[i][j] == 0) {
for(int k=1; k<=1000; k++) {
if(is_ok(i-k,j-k)) queen[i-k][j-k] = 1;
else break;
}
for(int k=1; k<=1000; k++) {
if(is_ok(i,j-k)) queen[i][j-k] = 1;
else break;
}
for(int k=1; k<=1000; k++) {
if(is_ok(i-k,j)) queen[i-k][j] = 1;
else break;
}
}
continue;
}
}
} int t; cin >> t;
while(t--)
{
int tp,n,m; scanf("%d %d %d", &tp,&n,&m);
if(tp == 1) {
int ans = king[1000-n+1][1000-m+1];
if(ans) printf("B");
else printf("G");
}
if(tp == 2) {
int ans = rook[1000-n+1][1000-m+1];
if(ans) printf("B");
else printf("G");
}
if(tp == 3) {
int ans = knight[1000-n+1][1000-m+1];
if(ans == 1) printf("B");
else if(ans == 2) printf("D");
else printf("G");
}
if(tp == 4) {
int ans = queen[1000-n+1][1000-m+1];
if(ans) printf("B");
else printf("G");
}
printf("\n");
} return 0;

}

HDU 5754 Life Winner Bo (博弈)的更多相关文章

  1. HDU 5754 Life Winner Bo 组合博弈

    Life Winner Bo Problem Description   Bo is a "Life Winner".He likes playing chessboard gam ...

  2. HDU 5754 Life Winner Bo (找规律and博弈)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5754 给你四种棋子,棋子一开始在(1,1)点,两个人B和G轮流按每种棋子的规则挪动棋子,棋子只能往右下 ...

  3. HDU 5754 Life Winner Bo(各类博弈大杂合)

    http://acm.hdu.edu.cn/showproblem.php?pid=5754 题意: 给一个国际象棋的棋盘,起点为(1,1),终点为(n,m),现在每个棋子只能往右下方走,并且有4种不 ...

  4. HDU 5754 Life Winner Bo (各种博弈) 2016杭电多校联合第三场

    题目:传送门 题意:一个国际象棋棋盘,有四种棋子,从(n,m)走到(1,1),走到(1,1)的人赢,先手赢输出B,后手赢输出G,平局输出D. 题解:先把从(n,m)走到(1,1)看做是从(1,1)走到 ...

  5. 【博弈论】HDU 5754 Life Winner Bo

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5754 题目大意: 4种棋子,象棋中的 1王,2车,3马,4后,选其一,B和G轮流走,不能往左上走,一 ...

  6. HDU 5754 Life Winner Bo

    四种棋子实质上都是一样的思路: 如果某位置的棋子,它下一步可以走到的位置中 能找到有后手胜的位置,那么该位置先手必胜. 如果某位置的棋子,它下一步可以走到的位置中 全是先手胜,那么该位置后手必胜. 其 ...

  7. hdu 5754 Life Winner Bo 博弈论

    对于king:我是套了一个表. 如果起点是P的话,则是后手赢,否则前手赢. 车:也是画图推出来的. 马:也是推出来的,情况如图咯. 对于后:比赛时竟然推错了.QAQ最后看了题解:是个威佐夫博奕.(2, ...

  8. hdu-5754 Life Winner Bo(博弈)

    题目链接: Life Winner Bo Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 131072/131072 K (Java/ ...

  9. hdu_5754_Life Winner Bo(博弈)

    题目链接:hdu_5754_Life Winner Bo 题意: 一个棋盘,有国王,车,马,皇后四种棋子,bo先手,都最优策略,问你赢的人,如果双方都不能赢就输出D 题解: 全部都可以直接推公式, 这 ...

随机推荐

  1. WindowManager.LayoutParams.type属性

    type 的取值: 应用程序窗口.      public static final int FIRST_APPLICATION_WINDOW = 1; 所有程序窗口的“基地”窗口,其他应用程序窗口都 ...

  2. Eclipse中Python插件PyDev的安装与配置流程

    安装PyDev插件的两种安装方法: 方法1.下载地址:http://sourceforge.net/projects/pydev/files/,将下载的PyDev解压(目前最新版本 PyDev 4.5 ...

  3. vi编辑器基本用法介绍

    vi是Linux系统中编写文件的工具 如果vi出现乱码情况,需要升级vi,命令如下: sudo apt-get install vim  //升级vi vi的启动方式有两种,直接使用vi命令和在vi命 ...

  4. HDU 1166 敌兵布阵 (线段树 单点更新)

    题目链接 线段树掌握的很差,打算从头从最简单的开始刷一波, 嗯..就从这个题开始吧! #include <iostream> #include <cstdio> #includ ...

  5. uva 10131 Is Bigger Smarter ? (简单dp 最长上升子序列变形 路径输出)

    题目链接 题意:有好多行,每行两个数字,代表大象的体重和智商,求大象体重越来越大,智商越来越低的最长序列,并输出. 思路:先排一下序,再按照最长上升子序列计算就行. 还有注意输入, 刚开始我是这样输入 ...

  6. iOS开发:Swift多线程NSOperation的使用

    介绍: NSOperation是基于GCD实现,封装了一些更为简单实用的功能,因为GCD的线程生命周期是自动管理,所以NSOperation也是自动管理.NSOperation配合NSOperatio ...

  7. UVa 10375 (唯一分解定理) Choose and divide

    题意: 求组合数C(p, q) / C(r, s)结果保留5为小数. 分析: 先用筛法求出10000以内的质数,然后计算每个素数对应的指数,最后再根据指数计算答案. #include <cstd ...

  8. eclipse无法与手机连上的解决方案

    在eclipse上开发android应用,有时候会遇到eclipse无法识别手机的问题,就算把数据线拔了又插,插了又拔,哪怕是重启eclipse 甚至是重启电脑,这个问题也依然是解决不了.这时候就非常 ...

  9. 完全二叉树的高度为什么是对lgN向下取整

    完全二叉树的高度为什么是对lgN向下取整呢? 说明一下这里的高度:只有根节点的树高度是0. 设一棵完全二叉树节点个数为N,高度为h.所以总节点个数N满足以下不等式: 1 + 21 + 22 +……+ ...

  10. ubuntu12.04下txt文件乱码如何解决

    :gsettings set org.gnome.gedit.preferences.encodings auto-detected "['UTF-8','GB18030','GB2312' ...