数字字符---------解题思路

这是一篇关于解决编程问题的博客,讨论了如何在有限的'0'-'9'字符集合中找出无法组成的最小正整数。解题思路包括区分'0'和其他字符,记录各字符出现次数,比较最小次数的字符来确定答案形式,并提供了实现代码。
摘要由CSDN通过智能技术生成

题目描述:

在十进制表示中,任意一个正整数都可以用字符’0’-‘9’表示出来。但是当’0’-‘9’这些字符每种字符的数量有限时,可能有些正整数就无法表示出来了。比如你有两个‘1’,一个‘2’,那么你能表示出11,12,121等等,但是无法表示出10,122,200等数。 
现在你手上拥有一些字符,它们都是’0’-‘9’的字符。你可以选出其中一些字符然后将它们组合成一个数字,那么你所无法组成的最小的正整数是多少?

输入描述:

第一行包含一个由字符’0’-‘9’组成的字符串,表示你可以使用的字符。
1 ≤字符串长度≤ 1000

输出描述:

输出你所无法组成的最小正整数

测试用例1:

输入:1234567890

输出:11

测试用例2:

输入:2233445556677889900111

输出:222

测试用例3:

输入:223344555667788990111

输出:100

解题思路:

本题无法组成的最小数的形式应该只有两种10...0(n个0)或者X...X(X为1到9)。

首先本题要找的是正整数,所以我们先得把0和其他字符分开考虑。

  1. 先记录‘1’~‘9’这9个字符出现的次数,然后找到出现次数最小的,这里次数相同时优先找值小的字符,比方说‘2’,‘3’都出现了2次,而其余的除‘0’外都出现了3次或其以上(0出现2次,下一条解释为什么),那么最小不能组成的数是222,和3无关。
  2. 将‘1’~‘9’中出现的最小次数和‘0’出现的次数比较,注意比较的时候‘0’的出现次数得加1。比方说上一条例子中,‘0’出现的次数为1的话,本题答案为100。所以说a[0]=1(0的次数)+1 <= a[2] = 2(2的次数)时,答案的形式为10...0;而a[0]=2 + 1 > a[2] = 2 时,答案形式为X...X。而且通过这个例子我们了解到答案的长度为最小次数加1(‘0’为加2),比方说1中的例子答案3个2(2出现2次),2中的例子答案100(0出现1次)
  3. 通过2我们总结出的方法:找‘1’~‘9’出现次数最少且值最小的数,和‘0’出现的次数加1进行比较。这里代码实现的时候为了简化,记录0出现次数的a[0]初值我直接赋为1,其余为0,输入字符串后,记录的0出现的次数比实际出现多了个1,然后排序直接用<algorithm>的stable_sort。num[]数组一开始是每个字符的标号,这时num[0]=0,a[]是对应字符出现的次数。比较函数cmp:两个数x,y出现次数a[x]<a[y]时返回true。sort完后,num[]数组中的num[0]就是出现次数最少的字符了。至于为什么用stable_sort,好处就是次数相同时,值小的排前面。这时我们判断次数num[0]是不是‘0’,如果是的话,就输出1;不是则输出num[0]。之后再输出a[num[0]]个num[0],注意这里a[]并没排序,还是原来的依次为0~9的出现次数。
  4. 之后我们考虑一下特殊情况:
  • 字符出现最小次数为0时,没有什么区别
  • 字符出现次数全部一样时,定为k次,比较的时候a[0]=k+1 > a[i](i为1~9),此时被挑出来的是1,根据步骤3中的方法最后的答案为1111...11(一共k+1个1)。而事实上它也的确是最小的不能组成的数。这样就顺利地解决了这道题。

实现代码:

#include<iostream>
#include<algorithm>
using namespace std;
int num[10]={0,1,2,3,4,5,6,7,8,9};
int a[10]={1};//出现的次数,‘0’的次数初值赋为1,其余为0
bool cmp(int x,int y)//设置比较函数,将10个字符按出现次数从少到多排列
{
    return a[x]<a[y];
}
int main()
{
    string str;
    cin>>str;
    for(auto c:str)
    {
        a[c-48]++;//记录字符出现次数
    }
    stable_sort(num,num+10,cmp);//次数相同时,值小的排在前面
    num[0]==0 ? cout<<1:cout<<num[0];
    for(int i=0;i<a[num[0]];cout<<num[0],i++);
}

 测试截图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值