Codeforces Round #350 (Div. 2) F. Restore a Number

题意:

小明写了一个大数字 n ,然后再这个数字后面又加了一个数字 kkn 的位数
现在小明把完整的数字传给了小红, 但是在传输的过程中出现了意外,小红收到的数字的内容是打乱的, 现在知道的是小明还记得 大数字 n 的一部分,也就是他的字串,让你还原这个数字 n, 且让这个数字 n 尽可能的小。
记住,不能又前导零, 一个单个的 零 是允许的。

输入是小红收到的数
还有小明记住的数

思路:

有一点很容易想到, 这个 n 很大,也就是 n 的位数很多,但是 n 的位数这个数字的位数也就不超过8位, 所以我们就可以枚举 n 的位数这个数字的位数

  • 首先判断这个位数是不是合法
    • 如果合法
      • 判断能不能找到最小的数输出。

首先判断这个位数是不是合法,
我们枚举的位数 x 和 真正剩下的数lens - x的位数是不是一样的,
如果是一样的,再看看枚举的位数可不可以由剩下的数组成。

如果位数合法判断能不能组成最小的数。
现在问题转化成了
有一些数字, 还有一个有数字组成的字符串t, 怎样组合才可以让组成的数最小。

首先考虑能不能组成数, 也就是剩下的数是不是都是 0,
如果都是 0, 0 的个数有多少个,
如果 0 的个数大于1,那就GG, 如果就 1 个, 直接输出来。

  • 如果 t 的开头是 0, 单独输出来。 那么 t 就一定不是在总串的开头
  • 如果 t 的开头不是 0, 我们就弄出来两个字符串
    • t 在总串的开头
    • t 不在总串的开头,这种情况有可能不存在,注意考虑,因为 剩余的数字中有可能只有0或者不剩余数字。
  • 最终两个串比较一下就好了。

反思:

一开始就没有想到过用两个串进行比较的事,
一开始想的就是直接把这个最小的串构造出来。就导致要考虑的细节特别多。 这里少一个东西,那里少一个东西。

下次再遇到这样的题,
给你一些数字, 和一个字符串,构造一个最小的数字出来,
两步走,

  • 判断t串开头是不是 0,是 0 直接处理
  • 不是 0, 构造两个串出来,进行比较。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+100;
void dbg() {cout << endl;}
template<typename T, typename... A> void dbg(T a, A... x) {cout << a << ' '; dbg(x...);}
#define logs(x...) {cout << #x << " -> "; dbg(x);}
int n,m,lens,lent,a[10],b[10],c[10];
char s[N],t[N],l[N],r[N];
bool solve(int x){  //判断当前数字的位数是不是满足条件。位数最多是 1e6, 所以 k 最大就是7位。一个一个判断。
    for (int i = 0; i < 10; ++i)
        c[i] = a[i];
    if (lens - x <= 0){
        return false;
    }
    int tmp = lens - x,y,len = 0;
    while(tmp){
        y = tmp % 10;
        len++;
        c[y]--;
        if (c[y] < 0) return false;
        tmp /= 10;
    }
    if (len != x) return false;  //我假定的位数 和 真实的位数是不是一样的,如果不是那就false。
    return true;
}
void put0(){  // t 串开头是 0 的情况。 
    bool vis = 1;
    for (int i = 1; i < 10; ++i){
        if (c[i] && vis){
            printf("%d",i);
            vis = 0;
            for (int j = 1; j <= c[0]; ++j)
                printf("0");
            printf("%s",t+1);
            for (int j = 1; j < c[i]; ++j)
                printf("%d",i);
        } else
        for (int j = 1; j <= c[i]; ++j)
            printf("%d",i);
    }
    if (vis) printf("%s\n",t+1);//如果剩下的数字全在t串中,要单独考虑
    printf("\n");
    return;
}
bool put(int emmm){
    int x = t[1] - '0',y = 0; 
    for (int i = 1; i < 10; ++i)
        y += c[i];
    y += x;
    if (y == 0 && emmm > 1) return 0;   //判断是不是全零, 如果是一个零还是满足条件的,否则不满足条件。
    if (x == 0){
        put0();   // 首先判断 t 串的开头,不能是零, 不然是零的话不可以放在总串的开头。
        return 1;
    }
    y = 0;
    for (int i = 1; i <= lent; ++i)
        l[y++] = t[i];
    for (int i = 0; i < 10; ++i)
        for (int j = 1; j <= c[i]; ++j)
            l[y++] = i + '0'; 

    y = 0;
    for (int i = 1; i <= 9; ++i)
        if (c[i]){
            r[y++] = i + '0';
            c[i] --;
            break;
        }
    if (y == 0){   // 判断 去除了T 串, 剩下的数字不能当头, 如果不能就直接输出 t 串当头。 
        printf("%s\n",l);
        return 1;
    }
    x = t[1] - '0';
    for (int i = 2; i <= lent; ++i){
        if (t[i] > t[i-1]) break;
        if (t[i] < t[i-1]) {
            x--;
            break;
        }
    }
    for (int i = 0; i < 10; ++i){
        for (int j = 1; j <= c[i]; ++j)
            r[y++] = i + '0';
        if (i == x){
            for (int j = 1; j <= lent; ++j)
                r[y++] = t[j];
        }
    }
    if (strcmp(l,r) <= 0){  //两个串进行比较。 
        printf("%s\n",l);
    } else printf("%s\n",r);
    return 1;
}
int main(){
    scanf("%s",s+1);
    scanf("%s",t+1);
    lens = strlen(s+1);
    lent = strlen(t+1);
    for (int i = 1; i <= lens; ++i)
        a[s[i] - '0'] ++;
    for (int i = 1; i <= lent; ++i){
        a[t[i] -'0'] --;
        b[t[i] -'0'] ++;
    }
    for (int i = 7; i > 0; --i){
        if (solve(i)) {
            if (put(lens - i)) return 0;
        }
    }
    return 0;
}
利用 TensorFlow 训练自己的目标识别器。本文内容来自于我的毕业设计,基于 TensorFlow 1.15.0,其他 TensorFlow 版本运行可能存在问题。.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值