【博弈论】RacingCar Trail trail

RacingCar Trail
(trail.cpp/in/out)


Problem

AliceBob为了打发时间开发了一个新游戏。在N*M的格点区域内开一辆小车,车子只向四个方向行驶(东南西北),不能驶出格点,同一个格子不能经过两次,格点中标记X的部分不能走。AliceBob轮流控制车子行走的方向,Alice控制第一步,将小车从起点移动到相邻的某个格点,之后Bob接手并移动小车至另一个相邻格点,etc


(上图中A表示Alice,B表示Bob

AliceBob都会采取最优策略,最终谁不能移动小车谁输。

现在Alice想知道地图上的哪些点作为起点自己有必胜策略,你能帮助她吗?


Input

第一行是地图长和宽,NM1<=N,M<=100

之后的N行是地图的描述,每行M个字符,.’表示该处为可走的空地,X’表示该处为不可走的障碍物。


Output

对于每组数据输出N行,每行M个字符。

i行的第j个字符表示从(i,j)位置开始游戏的结果。

如果Alice有必胜策略,输出A’,否则输出B’

如果该点为障碍物,输出X’.


SampleInput

11

.

SampleOutput

B


SampleInput

33

...

.X.

...

SampleOutput

AAA

AXA

AAA


SampleInput

14

....

SampleOutput

AAAA


SampleInput

33

X.X

...

X.X

SampleOutput

XBX

BAB

XBX


SampleInput

58

........

.XX.XXX.

.X..X...

.X.XX.X.

........

SampleOutput

BABABABA

AXXBXXXB

BXBAXABA

AXAXXBXB

BABABABA








昨天的考试题,似乎可以用博弈论做。。。。。

ZQZ大神说找增广路

而我们坚信博弈论可以做,就搞了一晚上。。。。。

结果只有80分,有些点要超时(肯定啦,没剪枝!)

但是不会剪枝,所以就只能80分了。。。。。



说一下博弈论的思路

我们先想想,既然A和B都会按照最有状态来走,A的下一步该B走,其中一个B是必胜,一个B是必败,那么A的状态?

对,肯定是必胜,因为既然有一个B是必败,那么A肯定会走向必败的那个B,然而A就必胜了

所以说总结一下就是:

当前点是A

               如果他已经无路可走,那么当前的A是必败态

               如果他周围的B有一个是必败态,那么当前A肯定是必胜态

B同理


然后我们发现,我们只需要知道当前点的必败或者是必胜,而跟A或B无关,所以我们就可以不用管当前是A或B了


但是这样只能过80分,应该要什么alpha-beta剪枝,现在不会。。。。

先把这个80分的代码放上,后面如果能写出alpha-beta剪枝再说嘛。。。。。


测评情况(Shell)


C++ TLE Code(80)

/*http://blog.youkuaiyun.com/jiangzh7
By Jiangzh*/
#include<cstdio>
#include<cstring>
const int N=100+10;
int n,m;
char map[N][N];
const int dx[]={0,0,-1,1};
const int dy[]={1,-1,0,0};
bool hash[N][N];
int res=-1;

bool dfs(int x,int y)
{
	for(int k=0;k<4;k++)
	{
		int nx=x+dx[k];
		int ny=y+dy[k];
		if(nx<0||nx>=n||ny<0||ny>=m) continue;
		if(map[nx][ny]=='X') continue;
		if(!hash[nx][ny])
		{
			hash[nx][ny]=1;
			bool flag=dfs(nx,ny);
			hash[nx][ny]=0;//一定要有回溯的过程啊!!!(有点像走迷宫)
			if(!flag) return 1;//有一个必败,那么当前就必胜
		}
	}
	return 0;//不是必胜,那么就是必败
}

int main()
{
	freopen("trail.in","r",stdin);
	freopen("trail.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++) scanf("%s",map[i]);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			if(map[i][j]=='X') printf("X");
			else{
				memset(hash,0,sizeof(hash));
				hash[i][j]=1;
				if(dfs(i,j)) printf("A");
				else printf("B");
			}
		}
		printf("\n");
	}
	return 0;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值