10422 - Knights in FEN(bfs+map判重)

注意马的行走是按"日"字,其他的按照bfs搜就行了。

因为少写了个句号调了我几个小时,郁闷!

/*bfs搜索,map判重,因为第一次用map,代码有点乱,将就一下吧*/
#include<cstdio>
#include<iostream>
#include<string>
#include<map>
#include<queue>
#include<cstring>
using namespace std;
int dx[]={-2,2,-2,2,-1,1,-1,1};
int dy[]={-1,-1,1,1,-2,-2,2,2};
int map1[5][5];
int map2[5][5]={{1,1,1,1,1},{2,1,1,1,1},{2,2,3,1,1},{2,2,2,2,1},{2,2,2,2,2}};
int x,y;
int dis[1050000];				//实际上不用开这么大= =
int tempmap[1050000][5][5];
int q[1050000];
int ans;
int flag;
int vis[5000];
map<string,bool> m;
void bfs()
{
	string s;
	char ss[25];
	int i,j,front,rear;
	int tot=0;
	memcpy(tempmap[1],map1,sizeof(map1));	
	front=rear=1;
	dis[rear]=0;
	q[rear++]=5*x+y;
	for(i=0;i<5;i++)
		for(j=0;j<5;j++)
		{
			ss[tot++]=(map1[i][j]+30);		//30是我随便加的,因为不想让字符是1,2,3。。
		}
	s=ss;
	m.clear();
	m.insert(pair<string,bool>(s,1));
	while(front<rear)
	{
		int xx=q[front]/5;			//分解x,y
		int yy=q[front]%5;		
		for(i=0;i<8;i++)
		{
			int nx=xx+dx[i];
			int ny=yy+dy[i];
			tot=0;
			if(nx>=0&&nx<5&&ny>=0&&ny<5)
			{
				memcpy(tempmap[rear],tempmap[front],sizeof(tempmap[front]));
				int t=tempmap[rear][nx][ny];
				tempmap[rear][nx][ny]=tempmap[rear][xx][yy];
				tempmap[rear][xx][yy]=t;			
				if(memcmp(tempmap[rear],map2,sizeof(map2))==0)
					{flag=dis[front]+1;return;}
				for(int k=0;k<5;k++)
					for(j=0;j<5;j++)
					{
						s[tot++]=tempmap[rear][k][j]+30;		
					}
				if(m.find(s)==m.end())
				{
					m.insert(pair<string,bool>(s,1));
					dis[rear]=dis[front]+1;
					q[rear++]=nx*5+ny;
				}
			}
		}		
		front++;
		if(dis[front]>=10) {flag=0;return;}
	}
}
int main()
{
	int t,i,j;
	char a[10];
	int s=0;	
	scanf("%d",&t);
	getchar();

	while(t--)
	{
		memset(dis,0,sizeof(dis));
		memset(vis,0,sizeof(vis));
		flag=0;
		for(i=0;i<=4;i++)
		{
			gets(a);
			for(j=0;a[j];j++)
				if(a[j]=='1') map1[i][j]=1;
				else if(a[j]=='0') map1[i][j]=2;
				else if(a[j]==' ') {map1[i][j]=3;x=i;y=j;}
		}
		if(memcmp(map1,map2,sizeof(map2))==0)
		{printf("Solvable in 0 move(s).\n");continue;}
		bfs();
		if(flag&&flag<=10) printf("Solvable in %d move(s).\n",flag);
		else printf("Unsolvable in less than 11 move(s).\n");
	}
	return 0;
}

/*
这是第二个样例的过程,想调试程序的可以用。
10110 
01 11
10111
01001
00000 

1011 
01011
10111
01001
00000

10111
01011
101 1
01001
00000

10111
01011
10111
0 001
00000

10111
01 11
10111
00001
00000

10111
01111
 0111
00001
00000

1 111
01111
00111
00001
00000

11111
01111
00 11
00001
00000

*/


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TommyTT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值