您的位置:首页 > 其它

洛谷P1132 数字生成游戏

2017-08-23 16:47 369 查看

P1132 数字生成游戏

题目描述

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

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

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

在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,模拟三种操作
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int n,m;
int s[10],l1,h,f[100010];
bool vis[100010];
struct node{
int x,step;
}cur,nxt;
int bfs(){
memset(vis,0,sizeof(vis));
cur.x=n;cur.step=0;
vis
=1;
queue<node>q;
q.push(cur);
while(!q.empty()){
cur=q.front();q.pop();
int num=cur.x;
int ss[10],l2=0;
while(num){
l2=l2+1;
ss[l2]=num%10;
num/=10;
}//把即将要转换的数变成数组
for(int i=1;i<=l2;i++){
for(int j=i+1;j<=l2;j++){//枚举交换的两个数
swap(ss[i],ss[j]);
int y=0;//记录更改后的数字
for(int k=l2;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<=l2;i++){//枚举删除某一位数字
int y=0;
for(int j=l2;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(l2<l1){//可以插数字
for(int i=1;i<=l2-1;i++){//枚举插在谁的后面
for(int j=ss[i]-1;j>ss[i+1];j--){//枚举插什么数字
int y=0;
/*for(int k=l2,l=1;k>=1;k--,l++){
y=y*10+ss[k];
if(l==i)
y=y*10+j;
}*/
for(int k=l2;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 v=n;f
=0;
while(v){s[++l1]=v%10;v/=10;}
int h;bfs();
for(int i=1;i<=m;i++){
scanf("%d",&h);
printf("%d\n",f[h]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: