HDU1195Open the Lock
题意&思路:
给你两个4位的数字,对每位数字可以+1或者-1,1-1变成9,9+1变成1,相邻两位还可以交换位置,最少需要多少步可以把第一串数字改成第二串。
求最少的距离,用bfs暴搜所有情况。
看到还可以用双向bfs做,一会补。
代码:
#include<bits/stdc++.h>
const int N=1e4+10;
const int mod=1e7+9;
const int maxn=0x3f3f3f3f;
const int minn=0xc0c0c0c0;
const int inf=99999999;
using namespace std;
int dis[2]={1,-1},num[9]={9,1,2,3,4,5,6,7,8},vis[N]={0},solve;
struct edge
{
int n[4],time;
}be,en;
int change(edge a)
{
int i,sum=0;
for(i=0;i<4;i++)
sum=sum*10+a.n[i];
return sum;
}
int bfs()
{
queue<edge> q;
q.push(be);
vis[change(be)]=1;
while(!q.empty())
{
edge pre=q.front(),temp;
int i,j;
q.pop();
if(change(pre)==solve)
return pre.time;
for(i=0;i<4;i++)
if(pre.n[i]!=en.n[i])
{
for(j=0;j<2;j++)
{
temp=pre;
temp.n[i]=num[(pre.n[i]+dis[j])%9];
temp.time=pre.time+1;
if(!vis[change(temp)])
{
q.push(temp);
vis[change(temp)]=1;
}
}
}
for(i=0;i<3;i++)
{
temp=pre;
temp.n[i]=pre.n[i+1];
temp.n[i+1]=pre.n[i];
if(!vis[change(temp)])
{
temp.time=pre.time+1;
vis[change(temp)]=1;
q.push(temp);
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t,i;
cin>>t;
while(t--)
{
memset(vis,0,sizeof(vis));
char c;
for(i=0;i<4;i++)
{
cin>>c;
be.n[i]=c-'0';
}
for(i=0;i<4;i++)
{
cin>>c;
en.n[i]=c-'0';
}
solve=change(en);
be.time=0;
int ans=bfs();
cout<<ans<<endl;
}
return 0;
}