魔板 Magic Squares

洛咕

分析:这种从初始状态到目标状态的搜索求步数和操作的题一般套路都是用BFS.这道题和八数码难题有点类似,我们把每个状态看做一个int类型的整数,用队列实现BFS,用map(数组会爆空间)标记每个状态,同时记录步数,操作,由谁转移过来等必要信息即可.

BFS的性质保证了第一个搜到的合法操作就是最短路径,这也是我们使用BFS求这种类型的题目的原因.

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#define ll long long
using namespace std;
inline int read(){
    int x=0,o=1;char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')o=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*o;
}
queue<int>q;
map<int,int>Map,dis,nxt,pre;
int Ans,ans[10005];
int main(){
	int t=0,s=12348765,b[10];
	for(int i=1;i<=8;++i)b[i]=read();
	t=b[1]*10000000+b[2]*1000000+b[3]*100000+b[4]*10000+b[8]*1000+b[7]*100+b[6]*10+b[5];
	if(s==t){puts("0");return 0;}
	q.push(s);dis[s]=0;Map[s]=1;
	while(q.size()){
		int u=q.front(),uu=u,v,sum=0,a[10];
		q.pop();
		if(u==t){
			printf("%d
",dis[u]);
			while(pre[u]){
				ans[++Ans]=pre[u];
				u=nxt[u];
			}
			break;
		}
		while(uu){
			a[++sum]=uu%10;
			uu/=10;
		}
		v=a[4]*10000000+a[3]*1000000+a[2]*100000+a[1]*10000+a[8]*1000+a[7]*100+a[6]*10+a[5];
		if(!Map[v]){Map[v]=1;dis[v]=dis[u]+1;pre[v]=1;nxt[v]=u;q.push(v);}
		v=a[5]*10000000+a[8]*1000000+a[7]*100000+a[6]*10000+a[1]*1000+a[4]*100+a[3]*10+a[2];
		if(!Map[v]){Map[v]=1;dis[v]=dis[u]+1;pre[v]=2;nxt[v]=u;q.push(v);}
		v=a[8]*10000000+a[3]*1000000+a[7]*100000+a[5]*10000+a[4]*1000+a[2]*100+a[6]*10+a[1];
		if(!Map[v]){Map[v]=1;dis[v]=dis[u]+1;pre[v]=3;nxt[v]=u;q.push(v);}
	}
	for(int i=Ans;i>=1;--i){
		if(ans[i]==1)printf("A");
		if(ans[i]==2)printf("B");
		if(ans[i]==3)printf("C");
	}
	printf("
");
    return 0;
}

原文地址:https://www.cnblogs.com/PPXppx/p/11266312.html