zoukankan      html  css  js  c++  java
  • [dp+博弈]棋盘的必胜策略

    链接:https://ac.nowcoder.com/acm/problem/21797
    来源:牛客网

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 32768K,其他语言65536K
    64bit IO Format: %lld

    题目描述

    有一个二维棋盘,棋盘有r行c列,棋盘中的每一个位置有如下四种情况
    'E': 表示出口,可能有多个
    'T': 只有一个,表示起点
    '#': 表示障碍
    '.': 表示空地

    牛牛和牛妹在这样一个棋盘上玩游戏,他们有一张写有整数k的卡片,一开始放置在起点的位置,现在牛牛和牛妹开始轮流操作,牛牛先操作
    当前操作的牛会选择上下左右其中一个方向移动卡片,每走一步,卡片上的数字减去1
    只能走到空地上, 或者走到出口,走到出口,游戏就会结束,卡片的数字变成0的时候游戏也会结束,不能再移动的牛会输掉游戏

    如果牛牛和牛妹都用最佳策略,请问谁会赢

    输入描述:

    第一行输入3个整数r,c,k
    接下来r行每行读入k个字符表示棋盘

    1 ≤ r,c ≤ 50, 1 ≤ k ≤ 100

    输出描述:

    如果牛牛有必胜策略,输出"niuniu"
    否则输出"niumei"
    示例1

    输入

    复制
    2 3 3
    T.#
    #.E

    输出

    复制
    niuniu
    示例2

    输入

    复制
    3 3 99
    E#E
    #T#
    E#E

    输出

    复制
    niumei
    示例3

    输入

    复制
    4 5 13
    #E...
    #...E
    E.T#.
    ..#..

    输出

    复制
    niuniu

    备注:

    子任务1:mac(r,c) <= 10
    子任务2:max(r,c) <= 20
    子任务3:无限制

    题意:一个r行c列的二维棋盘,有障碍物‘#’和空地‘.’,有多个出口’E‘和一个起点’T‘,从起点开始可以走k步,若k变为0时则把牌的k变为0的这个牛取胜,若能在k步或k步内到达任意一个终点E,则把牌移动到终点的那个牛胜,现在牛牛先手,问牛牛能否必胜
    思路:如果从起点出发能到达一个必胜状态,则先手必胜
    现在从起点开始搜索周围的点
    先看这个点如果上一个牛把牌移动到了当前这个点使得牌的k变为0或到达终点,则现在这只牛就输了,返回一个0
    若这个点不发货上述条件,则再从这个点出发,看周围上下左右的点,若能走在棋盘内且还剩余步数,下一步能走到一个点使下一个牛输,则此点是可使这个牛赢的点,否则,若从这个点出发,下一步走不到一个点使下一个牛输的点,则此点是可使这个牛输的点

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int amn=1e2+1;
     4 char mp[51][51];
     5 int dp[51][51][amn],r,c,k,dic[5][3]={{0,1},{0,-1},{1,0},{-1,0}},dx,dy,si,sj;
     6 int dfs(int x,int y,int k){
     7     if(k<=0||mp[x][y]=='E')return dp[x][y][k]=0;///如果上一个牛把牌移动到了当前这个点使得牌的k变为0或到达终点,则现在这只牛就输了,返回一个0
     8     if(dp[x][y][k]!=-1)return dp[x][y][k];      ///如果这个点被走过了,返回这个状态      
     9     for(int i=0;i<4;i++){
    10         dx=x+dic[i][0];
    11         dy=y+dic[i][1];
    12         if(dx>=1&&dx<=r&&dy>=1&&dy<=c&&mp[dx][dy]!='#'&&k>0&&!dfs(dx,dy,k-1))    ///若从这个点出发,能走在棋盘内且还剩余步数,下一步能走到一个点使下一个牛输,则此点是可使这个牛赢的点
    13             return dp[x][y][k]=1;
    14     }
    15     return dp[x][y][k]=0;                       ///若从这个点出发,下一步走不到一个点使下一个牛输的点,则此点是可使这个牛输的点
    16 }
    17 int main(){
    18     ios::sync_with_stdio(0);
    19     cin>>r>>c>>k;
    20     for(int i=1;i<=r;i++){
    21         for(int j=1;j<=c;j++){
    22             cin>>mp[i][j];
    23             if(mp[i][j]=='T'){si=i,sj=j;}
    24         }
    25     }
    26     memset(dp,-1,sizeof dp);
    27     if(dfs(si,sj,k)==1)printf("niuniu
    ");  ///如果从起点出发能到达一个必胜状态,则先手必胜
    28     else printf("niumei
    ");
    29 }
    30 /***
    31 一个r行c列的二维棋盘,有障碍物‘#’和空地‘.’,有多个出口’E‘和一个起点’T‘,从起点开始可以走k步,若k变为0时则把牌的k变为0的这个牛取胜,若能在k步或k步内到达任意一个终点E,则把牌移动到终点的那个牛胜,现在牛牛先手,问牛牛能否必胜
    32 如果从起点出发能到达一个必胜状态,则先手必胜
    33 现在从起点开始搜索周围的点
    34 先看这个点如果上一个牛把牌移动到了当前这个点使得牌的k变为0或到达终点,则现在这只牛就输了,返回一个0
    35 若这个点不发货上述条件,则再从这个点出发,看周围上下左右的点,若能走在棋盘内且还剩余步数,下一步能走到一个点使下一个牛输,则此点是可使这个牛赢的点,否则,若从这个点出发,下一步走不到一个点使下一个牛输的点,则此点是可使这个牛输的点
    36 ***/
  • 相关阅读:
    [编程语言][java][java se]java泛型中? T K V E含义(学习)
    Effective C++ 第二版 10) 写operator delete
    Cocos2d-x C++调用Android弹出提示框
    面试宝典 问题记录
    送给初入大学的工科男们一篇童话
    二叉树遍历
    webservice的讲解
    在JNI中新开线程遇到问题
    jni调试3(线程调试env变量问题)
    eMMC(KLM8G2FE3B)
  • 原文地址:https://www.cnblogs.com/Railgun000/p/11297417.html
Copyright © 2011-2022 走看看