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\n",f[h]);
    }
    return 0;
}

数字生成游戏

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

时间: 2024-11-08 17:28:05

P1132 数字生成游戏的相关文章

洛谷P1132 数字生成游戏

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

P1132 数字生成游戏 结题报告

题目 解题思路 暴力bfs,用字符串来模拟这三种操作 用字符串的优点:代码易想,简单易懂,降低思考复杂度,删除/插入操作直接截取字符串再相加就完事了(.substr函数) 缺点:相对直接用数字操作更慢(可能只有我的慢) 交换 最简单的操作,直接交换字符串中的两个字符,然后对应到数字,判断是否要加入队列 删除 枚举删除位置,截取左右两段字符串相加得出新的字符串 插入 枚举插入位置(不能在两头),然后截取左右两段字符串,中间再加一个字符 每次记录答案时需要先将字符串转换为数字 (方法与快读的一样)

洛谷P1132 数字生成计划 广搜

洛谷P1132 数字生成计划 广搜 三种操作 因为要步数最少,所以广搜 1 #include <bits/stdc++.h> 2 #define For(i,j,k) for(int i=j;i<=k;i++) 3 using namespace std ; 4 5 const int N = 1000011 ; 6 struct node{ 7 int a,ans ; 8 }; 9 bool flag[N] ; 10 int f[N] ; 11 queue<node> q;

简单的猜数字小游戏

/** 简单的猜数字小游戏 要求如下: 用户输入想猜测数字的范围,输入1000则是0~1000之内的数字,程序就会内置一个 1 到 1000 之间的数字作为猜测的结果,由用户猜测此数字,用户每猜测一次,由系统提示猜测结果:大了.小了或者猜对了:直到用户猜对结果,则提示游戏结束.用户可以提前退出游戏,即,游戏过程中,如果用户录入数字0则游戏终止.加入新功能: 记次猜测次数功能,提示游戏开始时间,计猜测总用时功能,提示游戏结束时间 思路:1.用户输入电脑生成的数值取值范围,接收并判断是否是合理数值?

c语言:编写猜数字小游戏。

编写猜数字小游戏. 程序: #include<stdio.h> #include<time.h> void menu() { printf("***欢迎来挑战猜数字游戏***\n"); printf("*****请选择开始或退出*****\n"); printf("******1.start 0.exit******\n"); } void game() { int num = 0; srand((unsigned)tim

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

1. [代码][Java]代码    package com.luiszhang.test; import java.util.Arrays; /** * NumberLotteryGame * 一个简单的数字彩票游戏类 * @author LuisZhang * 参考了core java 8th中的例3-7的设计思想 */public class NumberLotteryGame {    private int gamesNumber;    // 生成游戏的数量,为以后多线程扩展做考虑 

java数字小游戏

今天开始学习java基础.首先是数据类型 1 整型(byte, short, int, long)2 浮点型(float,double)3字符型(char)4布尔型(boolean). 利用所学的知识,做了一个关于数字的游戏. import java.util.Random;  //引入随机import java.util.Scanner;//引入引用类型public class Zuoye{    public static void main(String[]args){        Ra

jquery开发的数字相加游戏(你能玩几分)

jquery开发的数字相加游戏,我在一轮中玩了632分(如下图),你能玩几分,哈哈... 我要试一试 下面贡献下这款“数字相加游戏”的开发过程. html部分: <div class="container"> <div class="how-to-play"> <h1> How to Play</h1> <p> 数字加法游戏-- 单击左侧的数字色块相加等于右上角的数字,当相等时,这几个色块消失. </

需求:有一个猜数字小游戏,请写一个程序实现在测试类中只能使用5次,超过5次提示:游戏试玩结束,请付费。

package cn.idcast4; import java.io.FileNotFoundException;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.io.Reader;import java.io.Writer;import java.util.Properties; /* * 需求:有一个猜数字小游戏,请写一个程序实现在测试类中只能使用5次, *