P1132 数字生成游戏

P1132 数字生成游戏

题目描述

小明完成了这样一个数字生成游戏,对于一个不包含0的数字s来说,有以下3种生成新的数的规则:

  1. 将s的任意两位对换生成新的数字,例如143可以生成314,413,134;

  2. 将s的任意一位删除生成新的数字,例如143可以生成14,13,43

  3. 在s的相邻两位之间s[i],s[i + 1]之间插入一个数字x,x需要满足s[i] < x < s[i + 1]。例如143可以生成1243,1343,但是不能生成1143,1543等。

现在小明想知道,在这个生成法则下,从s开始,每次生成一个数,可以用然后用新生成的数生成另外一个数,不断生成直到生成t至少需要多少次生成操作。

另外,小明给规则3又加了一个限制,即生成数的位数不能超过初始数s的位数。若s是143,那么1243与1343都是无法生成的;若s为1443,那么可以将s删除4变为143,再生成1243或1343。

输入输出格式

输入格式:

输入的第一行包含1个正整数,为初始数字s。

第2行包含一个正整数m,为询问个数。

接下来m行,每行一个整数t(t不包含0),表示询问从s开始不断生成数字到t最少要进行多少次操作。任两个询问独立,即上一个询问生成过的数到下一个询问都不存在,只剩下初始数字s。

输出格式:

输出包括m行,每行一个正整数,对每个询问输出最少操作数,如果无论。

输入输出样例

输入样例#1:
143
3
134
133
32
输出样例#1:
1
-1
4

说明

143 -> 134

133无法得到

143 -> 13 -> 123 -> 23 -> 32

对于20%的数据,s < 100;

对于40%的数据,s < 1000;

对于40%的数据,m < 10;

对于60%的数据,s < 10000;

对于100%的数据,s < 100000,m ≤ 50000。

思路:

  bfs搜索 模拟三种规则

  bfs处理了由s经规则变换的所有组合,并f[x]记录了到x这种组合所需的转换步数

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

int len1,len2,s[10],ss[10],f[100010];
bool vis[100010];
int n,m,h;
struct Node{
    int x,step;
}cur,nxt;

int bfs() {
    memset(vis,0,sizeof(vis));
    cur.x=n;
    cur.step=0;
    vis[n]=1;
    queue<Node>q;
    q.push(cur);
    while(!q.empty()) {
        cur=q.front();
        q.pop();
        int num=cur.x;
        int len2=0;
        while(num) {
            len2=len2+1;
            ss[len2]=num%10;
            num/=10;
        }
        for(int i=1; i<=len2; i++) {
            for(int j=i+1; j<=len2; j++) {
                swap(ss[i],ss[j]);
                int y=0;
                for(int k=len2; k>=1; k--)
                    y=y*10+ss[k];
                nxt.step=cur.step+1;
                nxt.x=y;
                if(!vis[nxt.x]) {
                    f[nxt.x]=nxt.step;
                    q.push(nxt); 
                    vis[nxt.x]=1;
                }
                swap(ss[i],ss[j]);
            }
        }
        for(int i=1; i<=len2; i++) {
            int y=0;
            for(int j=len2; j>=1; j--) {
                if(j==i) continue;
                y=y*10+ss[j];
            }
            nxt.step=cur.step+1;
            nxt.x=y;
            if(!vis[nxt.x]) {
                f[nxt.x]=nxt.step;
                q.push(nxt); 
                vis[nxt.x]=1;
            }
        }
        if(len2<len1) {
            for(int i=1; i<=len2-1; i++) {
                for(int j=ss[i]-1; j>ss[i+1]; j--) {
                    int y=0;
                    for(int k=len2; k>i; k--) 
                        y=y*10+ss[k];
                    y=y*10+j;
                    for(int k=i; k>=1; k--)
                        y=y*10+ss[k];
                    nxt.x=y;
                    nxt.step=cur.step+1;
                    if(!vis[nxt.x]) {
                        f[nxt.x]=nxt.step;
                        q.push(nxt); 
                        vis[nxt.x]=1;
                    }
                }
            }
        }
    }
    return -1;
}

int main() {
    memset(f,-1,sizeof(f));
    scanf("%d%d",&n,&m);
    int temp=n;
    f[n]=0;
    while(temp) {
        s[++len1]=temp%10;
        temp/=10;
    }
    bfs();
    for(int i=1; i<=m; i++) {
        scanf("%d",&h);
        printf("%d
",f[h]);
    }
    return 0;
}
数字生成游戏

 自己选的路,跪着也要走完!!!

原文地址:https://www.cnblogs.com/wsdestdq/p/7497094.html