Time Limit: 1 second

Memory Limit: 128 MB

【问题描述】

小明完成了这样一个数字生成游戏,对于一个不包含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。

【输入文件】输入文件gen.in的第一行包含1个正整数,为初始数字s。

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

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

一个询问生成过的数到下一个询问都不存在,只剩下初始数字s。

【输入格式】

输出文件gen.out包括m行,每行一个正整数,对每个询问输出最少操作数,如果无论如何都不能生成t则输出-1。

【输出格式】

输出文件divide_b.out仅包含一个正整数,即每段和最大值最小为多少。

【数据规模】

对于20%的数据,s < 100;对于40%的数据,s < 1000;对于40%的数据,m < 10;对于60%的数据,s < 10000;对于100%的数据,s < 100000,m ≤ 50000。

Sample Input1

143
3
134
133
32

Sample Output1

1
-1
4

【样例解释】

143 -> 134 133无法得到 143 -> 13 -> 123 -> 23 -> 32

【题解】

这题的输入范围不大。

所以可以用一个1..100000的布尔型数组进行判重。

但是对于C++选手,对字符串的操作不能单纯的用string类。

要把数字用整形存下来。然后一个一个截出来。

然后用乘10的方法一个一个接上去。

然后要预处理出能到达哪些数字以及到达所需要的步骤数目,然后对于询问直接输出就可以了。

【代码】

#include <cstdio>
#include <cstring> struct data //用来当做队列的数据类型
{
int step,s;
}; int tl = 0,chushi;
int bo[100000]; //用来判重 data team[100000]; //队列要开到10W才够用 void input_data()
{
memset(bo,255,sizeof(bo)); //把bo数组一开始设置为-1
scanf("%d",&chushi); //输入初始的数字
} void ex_change(int &a,int &b) //把字符a和字符b进行交换
{
int t;
t = a;
a = b;
b = t;
} int zhuanshuzi(int a[])//把a数组转成一个整形数字。
{
int dd = 0;
for (int i = 1;i<=a[0];i++) //如果是0就不乘(因为根据规则数字中是不会出现0的)
if (a[i]!=0) //这一点可以利用起来。当做是去除某个数字的方法。
dd=dd*10+a[i];
return dd;
} void bfs() //进行广搜
{
bo[chushi] = 0;
int head = 0,tail = 1;
team[1].s = chushi;
team[1].step = 0;
while (chushi>0) //获取这个数字它的位数 这个数字有备份所以除掉没事(已经放到队列中去了)
{
tl++;
chushi/=10;
}
while (head != tail) //如果头结点 不等于尾节点
{
head++;
int ss = team[head].s,step0 = team[head].step,shuzi = team[head].s;
int l = 0 ;
int b[11],a[11];
while (ss > 0) //把头结点的每一位都存到b数组当中去。
{
l++;
b[l] = ss % 10;
ss = ss /10;
}
b[0] = l; //记录下这个数字的位数 放在a[0]
a[0] = l;
for (int i = 1;i <= l;i++) //因为那样获取是逆序的,所以再把它反过来
a[i] = b[l-i+1];
for (int i = 1;i <= l-1;i++)
for (int j = i+1;j <= l;j++) //枚举所有的交换组合
if (a[i]!=a[j])
{
ex_change(a[i],a[j]); //交换这两个位置
int temp = zhuanshuzi(a); //转成整形数字
if (bo[temp] ==-1) //如果这个状态之前没有达到过
{
bo[temp] = step0+1; //记录下到达它的最小步骤数。
tail++; //加到尾节点上
team[tail].s = temp;
team[tail].step = bo[temp];
}
ex_change(a[i],a[j]);//再变回来
} if (l > 1) //如果这个数字的长度大于1,则可以删除掉一个数字以获取一个新的数字
for (int i = 1;i<=l;i++)
{
int tt = a[i];
a[i] = 0; //置为0,转的时候就不会除了。
int temp = zhuanshuzi(a);//把这个序列转换成一个整形数字
if (bo[temp] ==-1) //没有到达过。就加到尾节点
{
bo[temp] = step0+1;
tail++;
team[tail].s = temp;
team[tail].step = bo[temp];
}
a[i] = tt;
} if (l < tl) //如果比原来输入的数字小。则可以再加插入一个数字。
{
for (int i = 2;i <= l;i++)
{
for (int j = a[i-1]+1;j<=a[i]-1;j++) //可以直接根据规则枚举能插入
{//哪些数字。
for (int k=l+1;k>=i+1;k--)//然后要把数字都往后移
a[k] = a[k-1];
a[i] = j;
a[0] = l+1;
int temp = zhuanshuzi(a);
if (bo[temp] ==-1)
{
bo[temp] = step0+1;
tail++;
team[tail].s = temp;
team[tail].step = bo[temp];
}
a[0] = l; //回溯到之前的位数
for (int k = i;k<=l;k++)//把移动的数字都撤回来
a[k]=a[k+1];
}
}
}
}
} void output_ans() //对于每一个询问都直接输出答案就可以了。
{
int m;
scanf("%d",&m);
for (int i = 1;i <= m;i++)
{
int x;
scanf("%d",&x);
printf("%d\n",bo[x]);
}
} int main()
{
//freopen("F:\\rush.txt","r",stdin);
input_data();
bfs();
output_ans();
return 0;
}

【u109】数字生成游戏(gen)的更多相关文章

  1. 洛谷P1132 数字生成游戏

    P1132 数字生成游戏 题目描述 小明完成了这样一个数字生成游戏,对于一个不包含0的数字s来说,有以下3种生成新的数的规则: 将s的任意两位对换生成新的数字,例如143可以生成314,413,134 ...

  2. P1132 数字生成游戏

    题目请见:传送门 以下为题解,直接从洛谷上搬过来的,还专门改了markdown,(汗) 宽搜 with 一些技巧 由于查询量很大,所以要预先处理所有答案 预处理当然是用BFS,并同时进行delete, ...

  3. 生成1-n之间的随机数-猜数字小游戏

    生成1-n之间的随机数 获取随机数 获取1-n之间的随机数,包含n,代码如下: // 导包 import java.util.Random; public class Test01Random { p ...

  4. java猜数字小游戏

    /* * * 猜数字小游戏 * * 先由系统生成一个2-100之间的随机数字, * * 然后捕获用户从控制台中输入的数字是否与系统生成的随机数字相同, * * 如果相同则统计用户所猜的次数,并给出相应 ...

  5. 【转】Java数字抽奖游戏核心代码

    1. [代码][Java]代码    package com.luiszhang.test; import java.util.Arrays; /** * NumberLotteryGame * 一个 ...

  6. [Python3 练习] 007 简单的猜数字小游戏

    题目:简单的猜数字小游戏 (1) 描述 程序随机生成一个数字,玩家用键盘输入所猜数字,在规定次数内猜对为胜. (2) 要求 程序随机生成一个 1 到 100 的自然数 有 7 次机会去猜 机会用尽之前 ...

  7. 简单的猜数字小游戏--Python

    猜数字小游戏: #coding=utf-8 import random   answer =random.randint(1,100) #生成随机数 n=int (input("Please ...

  8. 算法:数字推盘游戏--重排九宫(8-puzzle)

    一.数字推盘游戏 数字推盘游戏(n-puzzle)是一种最早的滑块类游戏,常见的类型有十五数字推盘游戏和八数字推盘游戏等.也有以图画代替数字的推盘游戏.可能Noyes Palmer Chapman在1 ...

  9. Java基础知识强化之IO流笔记70:Properties练习之 如何让猜数字小游戏只能玩5次的案例

    1. 使用Properties完成猜数字小游戏只能玩5次的案例: 2. 代码实现: (1)猜数字游戏GuessNumber: package cn.itcast_08; import java.uti ...

随机推荐

  1. PHP: php_ldap.dll不能加载解决方案

    PHP: php_ldap.dll不能加载解决方案 php.ini中开启 ldap的扩展后,重启服务:phpinfo();中没有ldap apache_error.log 提示:PHP Warning ...

  2. 6.在单机上实现ZooKeeper伪机群/伪集群部署

    转自:https://blog.csdn.net/poechant/article/details/6633923

  3. Android Studio com.android.dex.DexException: Multiple dex files define(重复引用包)

    如果你用Android Studio开发,并且要用其他项目作为library,这个问题是很容易出现的.出现这个问题的原因是包的重复引用,意思就是在你自己的项目中引用了某个包,而被你作为library的 ...

  4. Java基础学习总结(38)——Lombok的使用和原理

    一.项目背景 在写Java程序的时候经常会遇到如下情形:  新建了一个Class类,然后在其中设置了几个字段,最后还需要花费很多时间来建立getter和setter方法  lombok项目的产生就是为 ...

  5. UVA 11437 - Triangle Fun 向量几何

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  6. 【hdu 6214】Smallest Minimum Cut

    [链接] 我是链接,点我呀:) [题意] 求最小割中最少的边数. [题解] 模板题 [代码] const int INF = 1e9; const int maxn = 1e3 + 7; const ...

  7. [Angular] New async 'as' syntax and ngIf.. else

    From Anuglar v4 above, we are able to using 'as' with async pipe. This allow as using 'new variable' ...

  8. Android 自己定义主菜单

    本文介绍一个超简单的自己定义主菜单.效果例如以下: 原理:事实上就是对原生的Dialog的一个简单的封装.并加上显示和隐藏的动画效果.再给控件加上回调事件. TestDialog.java publi ...

  9. Altium Designer画原理图时要紧凑

    之所以要紧凑,是为了方便打印到纸上,一般原理图也都用A4纸去画, 这样打印到纸上看起来不会太小,也不会太大.

  10. HDU 1251统计难题 字典树

    字典树的应用. 数据结构第一次课的作业竟然就需要用到树了!!!这不科学啊.赶紧来熟悉一下字典树. 空间开销太大T T #include<cstdio> #include<cstrin ...