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. Oracle中创建视图

    Oracle的数据库对象分为五种:表,视图,序列,索引和同义词. 视图是基于一个表或多个表或视图的逻辑表,本身不包含数据,通过它可以对表里面的数据进行查询和修改.视图基于的表称为基表. 视图是存储在数 ...

  3. Qt之QTableView添加复选框(QAbstractTableModel)

    简述 使用QTableView,经常会遇到复选框,要实现一个好的复选框,除了常规的功能外,还应注意以下几点: 三态:不选/半选/全选 自定义风格(样式) 下面我们介绍一下常见的实现方式: 编辑委托. ...

  4. onkeypress与onkeydown及 oncopy和onpaste 事件区别详细说明

    onkeypress与onkeydown 具体区别: 1. 一个放开一个没有放开,onkeydown 先于 onkeypress 发生. 2.onkeypress 无法系统按钮. 2.onkeydow ...

  5. POJ 1577 Falling Leaves

    题意:给出一些字符串,从上到下的建树,输出其前序遍历 像前面那一题一样,先建树,然后再递归前序遍历 不过想像上一题那样用数组建树,建树和上题一样的办法,可是应该怎么输出前序遍历呢= = 还是看的题解= ...

  6. ASP.NET MVC实现多个按钮提交事件

    有时候会遇到这种情况:在一个表单上需要多个按钮来完成不同的功能,比如一个简单的审批功能. 如果是用webform那不需要讨论,但asp.net mvc中一个表单只能提交到一个Action处理,相对比较 ...

  7. 自定义View,圆形头像

    1. 效果图 2. xml中 <com.etoury.etoury.ui.view.CircleImg android:id="@+id/user_info_head_img" ...

  8. hdu 4666 Hyperspace(多维度最远曼哈顿距离)

    献上博文一篇http://hi.baidu.com/byplane747/item/53ca46c159e654bc0d0a7b8d 设维度为k,维护(1<<k)个优先队列,用来保存0~( ...

  9. 在android中进行视频的分割

    最近项目有个需求要对录制的视频进行分割,查了很多资料,看到ffmpeg可以对视频进行分割.上网找到别人基于android的开源ffmpeg,终于编译成功ffmpeg.so.但是要使用的话还要查ffmp ...

  10. 正在连接...ORA-12541: TNS: 无监听程序

    明明已经在Net Configuration Assistant中配置过监听程序并启动过.但在测试本地网络服务名配置中扔提示以上错误"正在连接...ORA-12541: TNS: 无监听程序 ...