E - What a Ridiculous Election(2016 北京)

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;
}



猜你喜欢

转载自blog.csdn.net/ac_blood/article/details/80266057