E - What a Ridiculous Election UVALive - 7672
给你一个五位数,问你12345最少变几步变成给你的数
要求
1、交换相邻的两个数
2、把一个数+1 (<=3次)%10
3、把一个数变成两倍 (<=2次)%10
开一个优先队列预处理出所有的情况,再o(1)判断即可
#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
int p[100050][5][5],a[6];
int n;
struct node
{
int step,id,t1,t2;
};
//
bool operator<(const node &x,const node &y)
{
return x.step>y.step;
}
priority_queue <node> q;
int cal(int x,int y)
{
int b[6];
for(int i=1;i<=5;i++)
b[i]=a[i];
if(x==1)
{
swap(b[y],b[y+1]);
}
else if(x==2)
{
b[y]=(b[y]+1)%10;
}
else
{
b[y]=(b[y]*2)%10;
}
int ans=0;
for(int i=1;i<=5;i++)
{
ans=ans*10+b[i];
}
return ans;
}
void bfs()
{
node e;
e.step=0,e.t1=e.t2=0,e.id=12345;
q.push(e);
while(!q.empty())
{
node u=q.top();
q.pop();
int num=u.id;
node v;
v.step=u.step+1;
for(int i=5;i>=1;i--)
{
a[i]=num%10;
num/=10;
}
for(int i=1;i<=4;i++)
{
int pp=cal(1,i);
v.t1=u.t1,v.t2=u.t2,v.id=pp;
if(p[pp][v.t1][v.t2]!=inf) continue;
p[pp][v.t1][v.t2]=v.step;
q.push(v);
}
if(u.t1<=2)
{
for(int i=1;i<=5;i++)
{
int pp=cal(2,i);
v.t1=u.t1+1,v.t2=u.t2,v.id=pp;
if(p[pp][v.t1][v.t2]!=inf) continue;
p[pp][v.t1][v.t2]=v.step;
q.push(v);
}
}
if(u.t2<=1)
{
for(int i=1;i<=5;i++)
{
int pp=cal(3,i);
v.t1=u.t1,v.t2=u.t2+1,v.id=pp;
if(p[pp][v.t1][v.t2]!=inf) continue;
p[pp][v.t1][v.t2]=v.step;
q.push(v);
}
}
}
}
int main()
{
memset(p,inf,sizeof(p));
for(int i=0; i<=3; i++)
{
for(int j=0; j<=2; j++)
{
p[12345][i][j]=0;
}
}
bfs();
while(~scanf("%d",&n))
{
int ans=inf;
for(int i=0;i<=3;i++)
{
for(int j=0;j<=2;j++)
{
ans=min(ans,p[n][i][j]);
}
}
if(ans==inf) printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}