HDU-5754 Life Winner Bo (博弈论)

好久没有整题目了,并不是没有好的题目整,只是自己懒了太懒了太懒了。。。赶紧整理几个题补一下自己的罪过。。。

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

题意:

n*m的棋盘,一枚棋子要从左上角(0,0)到右下角,两个人轮流移动,谁移动到最后一步谁胜利,移动规则如下,有四种棋子:

1、king 国王     向右,向下,或者向右下移动一格

2、castle 车      向右,或者向下移动任意格

3、knight 马      向2*3的矩阵的另一个角移动

4、queen 王后  移动到同一行、列、斜线的任意位置

思路:

很明显这个是一个博弈的题目。他好在有四种棋子,分别对应四种走法,也就是将四个博弈结合在了一起。

将棋盘看作两堆石子,棋子移动取就是两堆石子,谁先取完谁胜利,一堆石子n-1个,一堆m-1个。

将四种博弈分别分析

1、king 国王     向右,向下,或者向右下移动一格,简化成石子问题就是可以在其中一堆取一个(向右、向下)或者在两堆中各取一个(向右下)。最终取到(0,0)   那就很明显了,最终结果是偶偶的,每一次偶偶都只能变成奇偶,偶奇,奇奇,然而这三种都能一次变成偶偶。于是就有答案了,谁面对偶偶的局势谁就输,对方只要保持每次都让他面对偶偶的局势就能保证取走最后的石子。这是对于n-1和m-1,对于n,m就是当n,m都为奇数时第一个人面对必败态,否则第一个人胜利。

2、castle 车    向右,或者向下移动任意格,简化成石子问题就是从某一堆中取出任意个,简单的nim博弈就能解决。同样也可以理解为一开始就保证和终点在一条对角线上,一定是先手赢,所以必胜策略就是先手移动到对角线上——然而如果一开始就是一个正方形,那先手肯定必败了。

3、knight 马      向2*3的矩阵的另一个角移动, Knight的移动方法跟马一样走日字,它比较难处理,因为它有和局的情况(比如某个人一直往右走,导致对面无路可走)使对手无法获得胜利…这样的情况看似麻烦,其实我们也可以用相同的思想分析必胜和必败状态。 我们先区分能分出胜负的局面和平局的局面,通过画图,我们可以发现(2,3)和(3,2)这样的情况是一定先手必胜的,而想(3,3)这种情况就无法达到,更进一步,我们发现(4,4)这种情况是一定必败的,而其他比它小的情况全部是平局。     更进一步,我们发现(5,6)这种情况也是必胜的:我们只需要先手走到(2,3)这个点就可以,在之前,我们知道(4,4)是先手必败,而在这里,我们如果把(2,3)看作起始点,把(5,6)看作终点,其组成的正方形和刚才那种情况一模一样:这说明这就是一种可以区分胜负的局面,从(4,4)开始,(7,7),(10,10)….均为先手必败,然而我们如果可以先手走到这样一种必败的局面,我们即是必胜的——而其余情况,全为和局。 到这里我们就可以写出最终结果了:当终点减去起点的坐标能被3整除的时候,先手必败;对于必胜条件,我们只需要判断(2,3)和(3,2)是否可以达到必败局面就可以了。

4、queen 王后  移动到同一行、列、斜线的任意位置,简化成石子问题就是可以在一堆中去任意个,也可以在两堆中取相同个。经典的威佐夫博弈问题,我们可以直接求解。

代码:

#include <bits/stdc++.h>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <set>

#define IO ios::sync_with_stdio(false);\
    cin.tie(0);    cout.tie(0);

typedef long long LL;
const long long INF = 0x3f3f3f3f;
const long long mod = 1e9+7;
const double PI = acos(-1.0);
const int maxn = 100000;
const char week[7][10]= {"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
const char month[12][10]= {"Janurary","February","March","April","May","June","July",
                           "August","September","October","November","December"
                          };
const int daym[2][13] = {{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
const int dir4[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
const int dir8[8][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}, {1, 1}, {-1, -1}, {1, -1}, {-1, 1}};

using namespace std;

int main()
{
    IO;
    int T;
    cin>>T;
    int logo=1;
    while(T--)
    {
        int t,n,m;
        cin>>t>>n>>m;
        n--;
        m--;
        if(t==1)
        {
            if(n%2==0&&m%2==0)
                cout<<"G"<<endl;
            else
                cout<<"B"<<endl;
        }
        if(t==2)
        {
            if(n==m)
                cout<<"G"<<endl;
            else
                cout<<"B"<<endl;
        }
        if(t==3)
        {
            if (n==m&&n%3==0)
                cout<<"G"<<endl;
            else if (n-1==m&&(n-1)%3==1)
                cout<<"B"<<endl;
            else if (n==m-1&&n%3==1)
                cout<<"B"<<endl;
            else
                cout<<"D"<<endl;
        }
        if(t==4)
        {
            int ak=0;
            int a=n;
            int b=m;
            double k;
            k=(sqrt(5.0)+1.0)/2.0;
            if(a>b)
            {
                t=a;
                a=b;
                b=t;
            }
            t=b-a;
            ak=(int)(t*k);
            if(a==ak)
                cout<<"G"<<endl;
            else
                cout<<"B"<<endl;
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/aiguona/p/8360525.html

时间: 2024-10-15 10:20:46

HDU-5754 Life Winner Bo (博弈论)的相关文章

HDU 5754 Life Winner Bo 组合博弈

Life Winner Bo Problem 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,B

【博弈论】HDU 5754 Life Winner Bo

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5754 题目大意: 4种棋子,象棋中的 1王,2车,3马,4后,选其一,B和G轮流走,不能往左上走,一开始棋子在(1,1),谁先走到(n,m)谁赢,无法走动算平局D. (n,m<=1000,case<=1000) 题目思路: [博弈论] 这题博弈论.怎样都输为必败,只能走到必败的为必胜. 王:(王可以横竖斜走一格)如果n个m均为奇数先手必败,否则必胜. 从3x3格子看,当n和m均为奇数时先手必败,

HDU 5754 Life Winner Bo 2016多校第三场1003

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5754 题意:给你一个n*m大小的棋盘,分别以国际象棋的国王.战车.骑士和皇后的走法从(1,1)走到(n,m),而且只能向右或者向下走,问谁有必胜的策略或者是两者平局. 题解:无论是哪一种移动,都可以注意到,如果从起点到某一个点有必胜的策略,那么再以必胜点作为起点可以走到下一个必胜点,也就是以小见大. 一.对于王的走法,可以注意到3*3大小的棋盘,从(1,1)到(3,3)后手是有必胜的策略的,对于N和

5754Life Winner Bo

给定一个n*m的矩阵,有四种棋子(国际象棋的王,王后,骑士,车).起点在(1,1)先走到(n,m)获胜. 分析:车是nim博弈.王后是威佐夫博弈.王和骑士写两个1000*1000的预处理即可. hdu5754Life Winner Bo 题目连接 1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 co

HDU 2149 Public Sale (博弈论经典)

Public Sale Problem Description 虽然不想,但是现实总归是现实,Lele始终没有逃过退学的命运,因为他没有拿到奖学金.现在等待他的,就是像FarmJohn一样的农田生涯. 要种田得有田才行,Lele听说街上正在举行一场别开生面的拍卖会,拍卖的物品正好就是一块20亩的田地.于是,Lele带上他的全部积蓄,冲往拍卖会. 后来发现,整个拍卖会只有Lele和他的死对头Yueyue. 通过打听,Lele知道这场拍卖的规则是这样的:刚开始底价为0,两个人轮流开始加价,不过每次加

HDU 1079 Calendar Game (博弈论-sg)

Calendar Game Problem Description Adam and Eve enter this year's ACM International Collegiate Programming Contest. Last night, they played the Calendar Game, in celebration of this contest. This game consists of the dates from January 1, 1900 to Nove

HDU 1517 A Multiplication Game(博弈论)

题目地址:HDU 1517 NP状态转换. 可以把题目的向上乘变成向下除.这样1是终结状态,设1的时候为必败点. 根据所有能一步到达必败点的点是必胜点,所以[x,x*9]必胜点:根据只能到达必胜点的点是必败点,所以[x*9+1,x*9*2]是必败点. 然后求解. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdli

HDU 6741 MUV LUV UNLIMITED (博弈论)

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=6741 题解 看完题解深刻地意识到自己是个智障. (1) 如果某个叶子节点的父亲有多于一个儿子,则为必胜态. 证明: 设去掉该叶子后为必败态,则直接删去该点先手必胜:若去掉该叶子后为必胜态,则先手将删去该点之后的必胜策略和这个叶子一同删去,依然是必胜策略. (2) 若不存在一个叶子结点父亲有多于一个儿子,考虑每个叶子(含)到深度最大的儿子个数多于\(1\)的祖先(不含)之间的点数.若所有的这些数都是偶

HDU Be the Winner [Anti-SG]

传送门 n堆,每次拿走至少一个,剩下的可以分成两堆.最后拿的人输 打表观察发现和Nim游戏一样...裸Anti-SG啊 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; typedef long long ll; const int N=1e6; inline int