Given a string which consists of five digits('0'-'9'), like "02943", you should change "12345" into it by as few as possible operations. There are 3 kinds of operations:
1. Swap two adjacent digits.
2. Increase a digit by one. If the result exceed 9, change it to it modulo 10.
3. Double a digit. If the result exceed 9, change it to it modulo 10.
You can use operation 2 at most three times, and use operation 3 at most twice.
As a melon eater(Chinese English again, means bystander), which candidate do you support? Please help him solve the puzzle.
Input
There are no more than 100,000 test cases.
Each test case is a string which consists of 5 digits.
Output
For each case, print the minimum number of operations must be used to change "12345" into the given string. If there is no solution, print -1.
Sample Input
12435
99999
12374
Sample Output
1
-1
3
【题意】
给出 一个串 问 最少经过多少次变化 使12345 变成这个串;
给出变换方式
1 : 交换相邻两项, 无限制次数
2 : 某一位增加一 限制 3次 超过10 %10
3: 某一位 *2 限制2次 超过10 %10
【思路】
用一个三维数字 ans【num】【op2】【op3】 预处理 代表 数字为num的 操作2 操作3 用的次数 进行BFS 预处理
每次操作都保证ans【num】【op2】【op3】里的数最小 这是 bfs 结束的关键
代码
#include <iostream> #include <stdio.h> #include <algorithm> #include <cmath> #include <math.h> #include <cstring> #include <string> #include <queue> #include <stack> #include <stdlib.h> #include <list> #include <map> #include <set> #include <bitset> #include <vector> #define mem(a,b) memset(a,b,sizeof(a)) #define findx(x) lower_bound(b+1,b+1+bn,x)-b #define FIN freopen("input.txt","r",stdin) #define FOUT freopen("output.txt", What a Ridiculous Election"w",stdout) #define S1(n) scanf("%d",&n) #define SL1(n) scanf("%I64d",&n) #define S2(n,m) scanf("%d%d",&n,&m) #define SL2(n,m) scanf("%I64d%I64d",&n,&m) #define Pr(n) printf("%d\n",n) #define lson rt << 1, l, mid #define rson rt << 1|1, mid + 1, r using namespace std; typedef long long ll; const double PI=acos(-1); const int INF=0x3f3f3f3f; const double esp=1e-6; const int maxn=1e5+5; const int MOD=1000000007; const int mod=1e9+7; int dir[5][2]={0,1,0,-1,1,0,-1,0}; int ans[maxn][5][5];//次数 struct node { int num[10]; int op2,op3; int step; }; int Q_sum(node A) { int sum=0; for(int i=1;i<=5;i++) { sum+=A.num[i]; sum*=10; } return sum/10; } void bfs(node t) { queue<node> Q; mem(ans,INF); t.op2=3;// +1 t.op3=2;// *2 t.step=0; Q.push(t); int n=Q_sum(t); ans[n][t.op2][t.op3]=0; while(!Q.empty()) { node u=Q.front(); Q.pop(); for(int i=2;i<=5;i++)//swap { node tu=u; swap(tu.num[i],tu.num[i-1]); int num=Q_sum(tu); tu.step++; if(tu.step>=ans[num][tu.op2][tu.op3]) continue; Q.push(tu); ans[num][tu.op2][tu.op3]=tu.step; } if(u.op2>0)//+1 { for(int i=1;i<=5;i++) { node tu=u; tu.op2--; tu.num[i]=(tu.num[i]+1)%10; int num=Q_sum(tu); tu.step++; if(tu.step>=ans[num][tu.op2][tu.op3]) continue; Q.push(tu); ans[num][tu.op2][tu.op3]=tu.step; } } if(u.op3>0)//*2 { for(int i=1;i<=5;i++) { node tu=u; tu.op3--; tu.num[i]=(tu.num[i]*2)%10; int num=Q_sum(tu); tu.step++; if(tu.step>=ans[num][tu.op2][tu.op3]) continue; Q.push(tu); ans[num][tu.op2][tu.op3]=tu.step; } } } } int main() { node temp; for(int i=1;i<=5;i++) temp.num[i]=i; bfs(temp); char str[12]; while(~scanf("%s",str+1)) { node b; for(int i=1;i<=5;i++) b.num[i]=str[i]-'0'; int n=Q_sum(b); int res=INF; for(int i=0;i<=3;i++) for(int j=0;j<=2;j++) { res=min(res,ans[n][i][j]); } if(res==INF) printf("-1\n"); else printf("%d\n",res); } return 0; }