【u109】数字生成游戏(gen)
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)的更多相关文章
- 洛谷P1132 数字生成游戏
P1132 数字生成游戏 题目描述 小明完成了这样一个数字生成游戏,对于一个不包含0的数字s来说,有以下3种生成新的数的规则: 将s的任意两位对换生成新的数字,例如143可以生成314,413,134 ...
- P1132 数字生成游戏
题目请见:传送门 以下为题解,直接从洛谷上搬过来的,还专门改了markdown,(汗) 宽搜 with 一些技巧 由于查询量很大,所以要预先处理所有答案 预处理当然是用BFS,并同时进行delete, ...
- 生成1-n之间的随机数-猜数字小游戏
生成1-n之间的随机数 获取随机数 获取1-n之间的随机数,包含n,代码如下: // 导包 import java.util.Random; public class Test01Random { p ...
- java猜数字小游戏
/* * * 猜数字小游戏 * * 先由系统生成一个2-100之间的随机数字, * * 然后捕获用户从控制台中输入的数字是否与系统生成的随机数字相同, * * 如果相同则统计用户所猜的次数,并给出相应 ...
- 【转】Java数字抽奖游戏核心代码
1. [代码][Java]代码 package com.luiszhang.test; import java.util.Arrays; /** * NumberLotteryGame * 一个 ...
- [Python3 练习] 007 简单的猜数字小游戏
题目:简单的猜数字小游戏 (1) 描述 程序随机生成一个数字,玩家用键盘输入所猜数字,在规定次数内猜对为胜. (2) 要求 程序随机生成一个 1 到 100 的自然数 有 7 次机会去猜 机会用尽之前 ...
- 简单的猜数字小游戏--Python
猜数字小游戏: #coding=utf-8 import random answer =random.randint(1,100) #生成随机数 n=int (input("Please ...
- 算法:数字推盘游戏--重排九宫(8-puzzle)
一.数字推盘游戏 数字推盘游戏(n-puzzle)是一种最早的滑块类游戏,常见的类型有十五数字推盘游戏和八数字推盘游戏等.也有以图画代替数字的推盘游戏.可能Noyes Palmer Chapman在1 ...
- Java基础知识强化之IO流笔记70:Properties练习之 如何让猜数字小游戏只能玩5次的案例
1. 使用Properties完成猜数字小游戏只能玩5次的案例: 2. 代码实现: (1)猜数字游戏GuessNumber: package cn.itcast_08; import java.uti ...
随机推荐
- Javascript和jquery事件--键盘事件KeyboardEvent
Js和jq事件—键盘事件KeyboardEvent 键盘事件keydown,keypress和keyup,还需要涉及到一个文本事件textInput. keydown,keypress和keyup事件 ...
- MyCat中间件:读写分离(转)
利用MyCat中间件实现读写分离 需要两步: 1.搭建MySQL主从复制环境 2.配置MyCat读写分离策略 一.搭建MySQL主从环境 参考上一篇博文:MySQL系列之七:主从复制 二.配置MyCa ...
- [D3] Creating a D3 Force Layout in React
Learn how to leverage d3's layout module to create a Force Layout inside of React. We'll take a look ...
- shell基础之符号与语法
shell脚本如今已经成为了一种非常普遍的脚本语言,之所以如此广泛的被应用,毋庸置疑它是有它的独到之处的.shell脚本语言和其它的语言比方说c/c++有何不同呢?c/c++等语言属于 ...
- 删除dataGridview中选中的一行或多行
一.实现的功能:可以删除一行或者多行数据,并在删除前提醒是否确定进行删除! DialogResult RSS = MessageBox.Show(this,"确定要删除选中行数据码?&quo ...
- POJ 3187 Backward Digit Sums 枚举水~
POJ 3187 Backward Digit Sums http://poj.org/problem?id=3187 题目大意: 给你一个原始的数字序列: 3 1 2 4 他可以相邻 ...
- springmvc hibernate整合
今天复习一下SpringMVC+Hibernate的搭建,本来想着将Spring-Security权限控制框架也映入其中的,但是发现内容太多 了,Spring-Security的就留在下一篇吧,这篇主 ...
- SVN—怎样安装SVNclient软件
一.怎样安装TortoiseSVN-1.7.12.24070-win32-svn-1.7.9版本号的SVNclient软件: a.下载TortoiseSVN-1.7.12 ...
- C#DateTime与Unix时间戳的转换
/// <summary> /// Unix时间戳转为C#格式时间 /// </summary> /// <param name="timeStamp" ...
- IT从业人员关注哪些问题
技术人员关注的问题非常多,但常见的至少有以下6种.特此整理,抓住核心问题,解决它. 一个人的精力和时间往往非常有限,能把核心问题都解决到位就是成功. 1.职业规划 大家从读小学开始,就是在为职业规划过 ...