关于此题多解(目前两个且无一般BFS解法

louziyang 2023-11-02 21:35:47 2023-11-05 21:26:41 19 返回题目

1.IDA*

优化1:设一个估价函数,当估价函数加上目前步数超过期望步数就直接退出。

优化2:d1[]={0,1,-1,0},d2[]={1,0,0,-1};在dfs时,前一次走的与此次走的下标和不能为3,否则情况就一样了。

卡点小常,青藤 22ms,洛谷o2 181ms

code

#include<bits/stdc++.h>
using namespace std;
short a[4][4];
short s[4][4]={
	{0,0,0,0},
	{0,1,2,3},
	{0,8,0,4},
	{0,7,6,5}
};
short d1[]={0,1,-1,0};
short d2[]={1,0,0,-1};
inline short f()
{
	short cnt=0;
	for(register short i(1);i<=3;++i)
		for(register short j(1);j<=3;++j)
			if(a[i][j]!=s[i][j])
				cnt++;
	return cnt-1;
}
inline bool IDA_star(short x,short y,short step,short maxstep,short pre)
{
	if(step==maxstep&&f()==-1)
		return 1;
	bool ans=0;
	for(register short i(0);i<=3;++i)
	{
		short nowx=x+d1[i];
		short nowy=y+d2[i];
		if(nowx<1||nowx>3||nowy<1||nowy>3||i+pre==3)
		continue;
		swap(a[x][y],a[nowx][nowy]);
		if(step+f()<=maxstep)
			ans=ans|IDA_star(nowx,nowy,step+1,maxstep,i);
		swap(a[x][y],a[nowx][nowy]);
		if(ans)
			return 1;
	}
	return 0;
}
int main()
{
	short x,y;
	for(register short i(1);i<=3;++i)
		for(register short j(1);j<=3;++j)
		{
			char ch;
			ch=getchar();
			a[i][j]=ch-'0';
			if(a[i][j]==0)
			x=i,y=j;
		}
	if(f()==-1)
	{
		printf("0");
		return 0;
	}
	int tot=0;
	while(++tot&&(!IDA_star(x,y,0,tot,-1)));
	printf("%d",tot);
	return 0;
}

2.A*

优化:A*即在priority_queue BFS里加个估价函数

青藤 31ms,洛谷o2 332ms

code

#include<bits/stdc++.h>
#define int long long
using namespace std;
string beginning=" ",s=" 123804765";
int d1[]={0,1,-1,0};
int d2[]={1,0,0,-1};
struct node{
	string str;
	int pre,step,x,y,hope;
	bool operator < (const node &x) const{
		return step+hope > x.step+x.hope;
	}
};
inline int f(string x)
{
	int cnt=0;
	for(int i(1);i<=9;++i)
		if(x[i]!=s[i])
		cnt++;
	return cnt-1;
}
priority_queue<node> q;
inline int A_star(int x,int y)
{
	q.push(node{beginning,-1,0,x,y,f(beginning)});
	while(!q.empty())
	{
		node t=q.top();
		q.pop();
		if(t.hope==-1)
			return t.step;
		for(register int i(0);i<=3;++i)
		{
			node tmp;
			int nowx=t.x+d1[i];
			int nowy=t.y+d2[i];
			if(nowx<1||nowx>3||nowy<1||nowy>3||i+t.pre==3)
				continue;
			tmp.step=t.step+1;
			tmp.pre=i;
			tmp.str=t.str;
			int s1=(t.x-1)*3+t.y,s2=(nowx-1)*3+nowy;
			swap(tmp.str[s1],tmp.str[s2]);
			tmp.hope=f(tmp.str);
			tmp.x=nowx;
			tmp.y=nowy;
			q.push(tmp);
		}
	}
	return -1;
}
signed main()
{
	int x,y;
	for(register int i(1);i<=3;++i)
		for(register int j(1);j<=3;++j)
		{
			char ch;
			int a;
			ch=getchar();
			a=ch-'0';
			beginning=beginning+ch;
			if(a==0)
			x=i,y=j;
		}
	printf("%d",A_star(x,y));
	return 0;
}
{{ vote && vote.total.up }}

共 1 条回复

wurenchao

(没有更多了)

#include<bits/stdc++.h> using namespace std; string gol="123804765"; map<string,int>mp; queueq; string s; int main(){

cin>>s;

mp[s]=0;
q.push(s);

while(!q.empty()){
	s=q.front();
	q.pop(); 
	
	if(s==gol){
		cout<<mp[s];
		return 0;
	}
	
	int p=s.find('0');
	
	//up +3
	if(p>=3){
		string tmp=s;
		swap(tmp[p],tmp[p-3]);
		if(mp.find(tmp)==mp.end()){
			mp[tmp]=mp[s]+1;
			q.push(tmp);
		}
	}
	
	//down -3
	if(p<=5){
		string tmp=s;
		swap(tmp[p],tmp[p+3]);
		if(mp.find(tmp)==mp.end()){
			mp[tmp]=mp[s]+1;
			q.push(tmp);
		}
	}
	
	//left -1
	if(p%3!=0){
		string tmp=s;
		swap(tmp[p],tmp[p-1]);
		if(mp.find(tmp)==mp.end()){
			mp[tmp]=mp[s]+1;
			q.push(tmp);
		}
	}
	
	//right +1
	if(p%3!=2){
		string tmp=s;
		swap(tmp[p],tmp[p+1]);
		if(mp.find(tmp)==mp.end()){
			mp[tmp]=mp[s]+1;
			q.push(tmp);
		}
	}
}
cout<<-1;
return 0;

}