【P1379】 八数码难题

【P1379】 八数码难题_第1张图片
https://www.luogu.com.cn/problem/P1379

map判重:

#include
#include
#include
#include
#include
using namespace std;
char a[4][4];
int dx[4]={
     -1,0,1,0};
int dy[4]={
     0,-1,0,1};
string ans="123804765";//最终目标 
string s;//开始状态 
int startx,starty;//开始坐标 
bool flag=true;
struct node
{
     
	int x,y;
	string s;
	int ans;
}Node;
int change(int i,int j)
{
     
	return i*3+j;
}
void bfs(int x,int y)
{
     
	Node.x=x,Node.y=y,Node.s=s,Node.ans=0;
	map<string,bool> mp;  mp[s]=true;
	if(s==ans)
	{
     
		cout<<0<<endl;
		return ;
	}
	queue<node> q;     q.push(Node);
	while(!q.empty()) 
	{
     
		node top=q.front(); q.pop();
		for(int i=0;i<4;i++)
		{
     
			int tempx=top.x+dx[i];
			int tempy=top.y+dy[i];
			if(tempx>=0&&tempx<3&&tempy>=0&&tempy<3)
			{
     
				string temp=top.s;
				int s1=change(tempx,tempy);
				int s2=change(top.x,top.y);
				swap(temp[s1],temp[s2]);
				if(!mp[temp])
				{
     
					node m;
					m.x=tempx,m.y=tempy,m.s=temp;
					mp[temp]=true;
					m.ans=top.ans+1;
					q.push(m);
					if(temp==ans) 
					{
     
						flag=false;
						cout<<m.ans<<endl;
						return ;
					}
				}
			} 
		}
	}
}
int main(void)
{
     
	for(int i=0;i<3;i++)
	{
     
		for(int j=0;j<3;j++)
		{
     
			cin>>a[i][j];
			s+=a[i][j];
			if(a[i][j]=='0') startx=i,starty=j;
		}	
	}
	bfs(startx,starty);
	return 0;
}

康托展开判重:

#include
#include
#include
#include
#include
using namespace std;
char a[4][4];
int dx[4]={
     -1,0,1,0};
int dy[4]={
     0,-1,0,1};
string ans="123804765";//最终目标 
string s;//开始状态 
int startx,starty;//开始坐标 
bool flag=true;
struct node
{
     
	int x,y;
	string s;
	int ans;
}Node;
int kang(string s)
{
     
	long long int sum=0;
	int a[9]={
     0,1,2,6,24,120,720,5040,40320};
	int x=8;
	for(int i=0;i<s.size();i++)
	{
     
		int temp=0;
		for(int j=i+1;j<s.size();j++)
		{
     
			if(s[i]>s[j])
			{
     
				temp++;
			}
		}
		sum+=temp*a[x--];
		
	}
	return sum;
}
int change(int i,int j)
{
     
	return i*3+j;
}
void bfs(int x,int y)
{
     
	Node.x=x,Node.y=y,Node.s=s,Node.ans=0;
	map<int,bool> mp;  mp[kang(s)]=true;
	if(s==ans)
	{
     
		cout<<0<<endl;
		return ;
	}
	queue<node> q;     q.push(Node);
	while(!q.empty()) 
	{
     
		node top=q.front(); q.pop();
		for(int i=0;i<4;i++)
		{
     
			int tempx=top.x+dx[i];
			int tempy=top.y+dy[i];
			if(tempx>=0&&tempx<3&&tempy>=0&&tempy<3)
			{
     
				string temp=top.s;
				int s1=change(tempx,tempy);
				int s2=change(top.x,top.y);
				swap(temp[s1],temp[s2]);
				if(!mp[kang(temp)])
				{
     
					node m;
					m.x=tempx,m.y=tempy,m.s=temp;
					mp[kang(temp)]=true;
					m.ans=top.ans+1;
					q.push(m);
					if(m.s==ans) 
					{
     
						flag=false;
						cout<<m.ans<<endl;
						return ;
					}
				}
			} 
		}
	}
}
int main(void)
{
     
	for(int i=0;i<3;i++)
	{
     
		for(int j=0;j<3;j++)
		{
     
			cin>>a[i][j];
			s+=a[i][j];
			if(a[i][j]=='0') startx=i,starty=j;
		}	
	}
	bfs(startx,starty);
	return 0;
}

在这里插入图片描述
康托展开节省了空间,但是时间稍微长了点。
但总的来说省的空间不少,还是非常棒的。

你可能感兴趣的:(搜索,算法)