P1379 八数码难题

Posted 幽殇默

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1379 八数码难题相关的知识,希望对你有一定的参考价值。

在这里插入图片描述
https://www.luogu.com.cn/problem/P1379

map判重:

#include<cstdio>
#include<iostream>
#include<map>
#include<queue>
#include<algorithm>
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<cstdio>
#include<iostream>
#include<map>
#include<queue>
#include<algorithm>
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;
}

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

以上是关于P1379 八数码难题的主要内容,如果未能解决你的问题,请参考以下文章

[LGOJ]P1379八数码难题[双向广搜].cpp

洛谷 P1379 八数码难题

P1379 八数码难题

洛谷P1379八数码难题

P1379 八数码难题

洛谷P1379 八数码难题