洛谷P1132 数字生成游戏
Posted Soda
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷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[n]=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[n]=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; }
以上是关于洛谷P1132 数字生成游戏的主要内容,如果未能解决你的问题,请参考以下文章