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. C#使用sharppcap实现网络抓包-----2

    虽然网上已经有了SharpSniffer 这一个SharpSniffer还是原创的无他,唯为学习工程文件下载:SharpSniffer.rar 1.创建套接字2.绑定到本机3.设置IOControl4 ...

  2. TCP建立连接和释放的过程,及TCP状态变迁图

    一.TCP报文格式 下面是TCP报文格式图: 重要字段介绍: (1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记. (2)确认序号:Ack序号,占 ...

  3. C#中跨线程读取控件值、设置控件值

    编写应用程序时,涉及到大量数据处理.串口通信.Socket通信等都会用到多线程,多线程中如何跨线程调用主界面或其他界面下的控件是一个问题,利用invoke和delegate可以解决. delegate ...

  4. php通过curl调用jpush接口实现消息的推送

    public function actionNotifyto() { //$regid = $_REQUEST['regid']; $url = 'https://api.jpush.cn/v3/pu ...

  5. (转)c语言_链表实例讲解(两个经典例子)

    建立一个学生成绩的线性链表,对其实现插入,删除,输出,最后销毁. #include <stdio.h>#include <stdlib.h> struct grade {    ...

  6. 【C#学习笔记】载入图片并居中

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  7. ORACLE 全局索引和本地索引

    Oracle数据库中,有两种类型的分区索引,全局索引和本地索引,其中本地索引又可以分为本地前缀索引和本地非前缀索引.下面就分别看看每种类型的索引各自的特点. 全局索引以整个表的数据为对象建立索引,索引 ...

  8. PHP的GD库函数大全

    GetImageSize作用:取得图片的大小[即长与宽]  用法:array GetImageSize(string filename, array [imageinfo]); ImageArc作用: ...

  9. ioctl()获取本地网卡设备信息

    获得eth0接口所有信息: #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #inclu ...

  10. Tombstone crash

    首先,android平台应用程序可能产生以下四种crash:App层:Force close crashANR crashNative层:Tombstone crashKernel层:Kernel p ...