棋盘的必胜策略(SG函数)

链接: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:无限制
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
char mp[55][55];
int r,c,k;
int sg[55][55][105];
int t[4][2]={0,1,0,-1,1,0,-1,0};
int getsg(int x,int y,int step){
	if(sg[x][y][step]!=-1) return sg[x][y][step];
	if(step==0) return sg[x][y][step]=0;
	if(mp[x][y]=='E') return sg[x][y][step]=0;
	bool book[10];
	memset(book,0,sizeof(book));
	for(int i=0;i<4;i++){
		int tx=x+t[i][0];
		int ty=y+t[i][1];
		if(tx<1||tx>r||ty<1||ty>c) continue;
		if(mp[tx][ty]=='#') continue;
		book[getsg(tx,ty,step-1)]=true;
	}
	for(int i=0;;i++){
		if(!book[i]) return sg[x][y][step]=i;
	}
}
int main(){
    scanf("%d%d%d",&r,&c,&k);
    for(int i=1;i<=r;i++){
    	scanf("%s",mp[i]+1);
	}
	int sx=0,sy=0;
	memset(sg,-1,sizeof(sg));
	for(int i=1;i<=r;i++){
		for(int j=1;j<=c;j++){
			if(mp[i][j]=='T'){
				sx=i;
				sy=j;
				break; 
			} 
		}
		if(sx&&sy) break;
	}
	int flag=getsg(sx,sy,k);
	if(flag==0) printf("niumei\n");
	else printf("niuniu\n");
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值