湖南大学第十四届ACM程序设计新生杯(重现赛)I:II play with GG(博弈论||DP)

14 篇文章 0 订阅
13 篇文章 0 订阅

链接:https://ac.nowcoder.com/acm/contest/338/I
来源:牛客网

题目描述

IG won the S championship and many people are excited, ii and gg are no exception. After watching the game, the two of them also want to play a game.
There is now an infinite chessboard with only one piece. Initially the pieces are placed at the (x, y) position (the board coordinates are counted from 0). They took turns to move the pieces. ii moves first.
There are three ways to move

  1. Move the piece to the left by one space (from (x, y) to (x-1, y)).
  2. Move the piece down one space (from (x, y) to (x, y-1)).
  3. Move the piece to the lower left by one space (from (x, y) to (x-1, y-1)).

It should be noted that the pieces cannot be removed from the board.
The first person who can not operate is judged negative (in other words, the first person who moves the piece to (0,0) wins).
Now give the initial coordinates x, y of the piece. Under the premise that both take the optimal strategy, please output the name of the winner (ii or gg).

输入描述:

The input contains only one line. Enter two integers x y to represent the initial coordinates of the piece. (0<=x, y<=1000)。

输出描述:

the winner’s name (ii or gg)。

示例

输入
1 1
输出
ii
输入
124 654
输出
gg

题意

ii和gg一起玩游戏,将一个石子放在棋盘(x,y)的位置,每次移动石子,必须把石子从(x,y)位置移动到(x,y-1)、(x-1,y)、(x-1,y-1)这三个位置中的其中一个位置,将石子移动到(0,0)点的人获胜,ii先移动

思路

一、博弈论
推出一部分的NP态,可以发现,当 x % 2 = = 0 x\%2==0 x%2==0并且 y % 2 = = 0 y\%2==0 y%2==0时,先手处于必败态

012345
0PNPNPN
1NNNNNN
2PNPNPN
3NNNNNN
4PNPNPN
5NNNNNN

N代表先手必胜,P代表先手必败

二、DP
根据题意可以知道,(0,1),(1,1),(1,0)点为N状态。
可以得出递推关系:当前点如果为P状态,那么这个点的前一步对应的三个可能的点一定都为N状态

AC代码

//NP
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,m;
    cin>>n>>m;
    if((n&1)||(m&1))
        cout<<"ii"<<endl;
    else
        cout<<"gg"<<endl;
    return 0;
}
//DP
#include<bits/stdc++.h>
#define ms(a,b) memset(a,b,sizeof(a))
const int maxn=1e3+10;
using namespace std;
int dp[maxn][maxn];
inline void init()
{
    ms(dp,0);
    dp[0][1]=dp[1][0]=dp[1][1]=1;
    for(int i=1;i<maxn;i++)
    {
        for(int j=1;j<maxn;j++)
            if(dp[i-1][j]&&dp[i][j-1]&&dp[i-1][j-1])
                dp[i][j]=0;
            else
                dp[i][j]=1;
    }
}
int main(int argc, char const *argv[])
{
    ios::sync_with_stdio(false);
    init();
    int n,m;
    cin>>n>>m;
    if(dp[n][m])
        cout<<"ii"<<endl;
    else
        cout<<"gg"<<endl;
    return 0;
}
  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值