一堆数字里,不能凑出的最小正整数
转自:【作者:FlushHip链接:https://www.nowcoder.com/discuss/70063】
很直观的思路,首先想想如果暴力该怎么搞,是不是要从1开始往上枚举。那么这题的思路差不多,从十进制位数开始枚举;
先不要看0,0这个字符待会再说,先来看看给出的这些字符能不能凑出一位数,能不能凑出一位数就看看1 - 9
是不是都有,如果都有,那么就可以;然后看看能不能凑出两位数,如果枚举到了两位数,那么就说明1 - 9
这些数字的个数大于等于1,什么时候会出现凑不出来的情况呢,对了,就是需要两个一样的数字时,比如1 - 9
这些数字的个数都为1,你就绝对凑不出11
,对吧;然后来看三位数,后面其实是一样的了,如果只有两个1
,是凑不出111
的,但是112
,129
这些数字都是可以的,因为1 - 9
这枚举三位数时就保证的这些字符的个数大于等于2……依次类推就可以了;
等等,好像还有0没有考虑,那么现在考虑一下。要凑最小三位数100
,最少需要两个0
,少了就不行,那么只有1
个0
的情况,能凑出来的最小的数就是10
;
想到这一步这个题就解决了啊,先统计1 - 9
的个数,然后找出里面的最小值,最小值表示这些数字至少能凑出几位数(这里还没有考虑字符0
),然后看下0
字符的个数是不是大于等于最小值减一,这里举个例子说明后面的步骤,比如1 - 9
每个字母都有3个,0
有3
个,1111
和10000
都是不可以凑出来的,答案就是1111
;比如1 - 9
每个字母都有3个,0
只有2
个,那么1111
和1000
都是不可以凑出来的,答案就是1000
。
#include <iostream> #include <string> #include <vector> using namespace std; int main() { for (string str; cin >> str;){ vector<int>used(10, 0);//用0初始化10个坑 int digit = -1, theMin = 0x3f3f3f3f;//计录出现次数theMin最少的数字(因为是从1开始,所以 该数字是出现次数最小的数字中最小数值的数) for (auto it = str.begin(); it!= str.end(); ++it) ++used[*it - '0'];//每个坑装对应编号出现的次数 //0----9出现的次数分别为:a[0]---a[9] for (int i= 1; i <= 9; ++i) if (theMin > used[i]) theMin = used[i], digit = i; //能凑出的最小位数是theMin位,假设theMin=3,那么最小的3位数的100,就要判断0个出现次数+1是否等于theMin if (used[0] +1<= theMin)//0的个数凑不够3位 cout << "1" + string(theMin, '0') << endl; else//0的个数能凑出来 cout << string(theMin + 1, digit + '0') << endl; } system("pause"); return 0; }