BFS+康托展开(洛谷1379 八数码难题)

在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。

输入格式:

输入初试状态,一行九个数字,空格用0表示

输出格式:

只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)

输入样例#1:

283104765

输出样例#1:

4思路就是bfs遍历所有的点,用康拓展开进行hash,然后用一个book数组进行判重即可~注意:string比较不能用==有时候会出Bug。book数组可以和dis合为一体,减少空间,增加代码的可读性~
#include<bits/stdc++.h>
using namespace std;
int temp[10]={1,1,2,6,24,120,720,5040,5040*9};
int dis[500000];

int Hash(string s)
{
	int len=s.length();
	int ans=0;
	for(int i=0;i<len;i++)
	{
		int tot=0;
		for(int j=i+1;j<len;j++)
			if(s[j]<s[i]) tot++;
		ans+=temp[len-i-1]*tot;
	}
	return ans;
}

string swap(string s,int i,int j)
{
	char c;c=s[i];s[i]=s[j];s[j]=c;
	return s;
}

string move(string s,int k)
{
	int i=s.find(‘0‘);
	if(k==1&&i>=3)
		s=swap(s,i,i-3);
	if(k==2&&i<=5)
		s=swap(s,i,i+3);
	if(k==3&&i%3!=0)
		s=swap(s,i,i-1);
	if(k==4&&i%3!=2)
		s=swap(s,i,i+1);
	return s;
}

bool Compare(string a,string b)
{
	for(int i=0;i<9;i++)
		if(a[i]!=b[i])
			return 0;
		return 1;
}

int BFS(string s)
{
	string t("123804765");//目标
	dis[Hash(s)]=1;
	queue<string> q;
	q.push(s);
	while(!q.empty())
	{
		string u=q.front();q.pop();
		if(Compare(u,t))
		 	return dis[Hash(u)]-1;
		for(int i=1;i<=4;i++)
		{
			string v=move(u,i);
			if(dis[Hash(v)]==0)
			{
				q.push(v);
				dis[Hash(v)]=dis[Hash(u)]+1;
			}
		}
	}
	return -1;
}

int main()
{
	string str;
	cin>>str;
	cout<<BFS(str)<<endl;
	return 0;
}

调试调了5h+也是醉了,我真是一天一天蒟蒻了。。~

时间: 2024-12-09 20:12:48

BFS+康托展开(洛谷1379 八数码难题)的相关文章

洛谷P1379 八数码难题

题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变. 输入输出格式 输入格式: 输入初始状态,一行九个数字,空格用0表示 输出格式: 只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)

洛谷 P1379 八数码难题

P1379 八数码难题 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变. 输入输出格式 输入格式: 输入初始状态,一行九个数字,空格用0表示 输出格式: 只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊

洛谷 P1379 八数码难题 Label:判重&amp;&amp;bfs

特别声明:紫书上抄来的代码,详见P198 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变. 输入输出格式 输入格式: 输入初试状态,一行九个数字,空格用0表示 输出格式: 只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数

poj 1077 八数码(BFS+康托展开)

1 /* 2 题意:八数码问题,给出3*3的矩阵含1~8以及x,给出一个符合的解使得移动后的矩阵的顺序为1~8,最后为x 3 4 题解:BFS 5 需要用到康托展开来表示状态,不然数组无法完全表示所有状态,这样BFS就无法判断找不到解的情况(status 6 的0ms,0KB究竟是怎么做到的,简直不能想象=.=) 7 */ 8 #include <cstdio> 9 #include <cstring> 10 #include <queue> 11 #include &

洛谷OJ P1379 八数码难题 解题报告

洛谷OJ P1379 八数码难题 解题报告 by MedalPluS 题目描述   在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变.   输入格式   输入初试状态,一行九个数字,空格用0表示   输出格式 只有一行,该行只有一个数字,表示从初始状态到

双向广搜+hash+康托展开 codevs 1225 八数码难题

codevs 1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.问题描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找

洛谷【P1379】八数码难题

P1379 八数码难题 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变. 输入输出格式 输入格式: 输入初试状态,一行九个数字,空格用0表示 输出格式: 只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊

洛谷P1219 八皇后

洛谷1219 八皇后 题目描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 上面的布局可以用序列2 4 6 1 3 5来描述,第i个数字表示在第i行的相应位置有一个棋子,如下: 行号 1 2 3 4 5 6  列号 2 4 6 1 3 5  这只是跳棋放置的一个解.请编一个程序找出所有跳棋放置的解.并把它们以上面的序列方法输出.解按字典顺序排列.请输出前3个解.最后一行是解的总个数. //

1225 八数码难题

1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.问题描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765