題目描述
給出一個數 \(n\),你需要將 \(n\) 寫成若干個數的和,其中每個數的十進位制表示中僅包含\(0\)和\(1\)。
問最少需要多少個數
輸入輸出格式
輸入格式:
一行 一個數 \(n(1≤n≤10^6)\)
輸出格式:
最少的數的個數,並給出一種方案。
輸入輸出樣例
輸入 #1
9
輸出 #1
9
1 1 1 1 1 1 1 1 1
輸入 #2
32
輸出 #2
3
10 11 11
分析
很顯然,對於任何一個數,我們把它分成只包含 \(0\) 和 \(1\) 的數字,這樣的最小劃分數一定不大於 \(9\)
因此在劃分的過程中一定不會出現借位的情況
因為如果出現借位的情況,那麼要想把借的那一位消去,至少需要 \(10\) 次操作
所以對於當前的數,我們可以存一下每一位能劃分出多少 \(1\)
然後按照劃分出 \(1\) 的個數從小到大排一下序
如果當前的個數不為 \(0\),那麼我們就從當前這一位開始一直到最後都減去當前的個數
這樣到最後,所有位上的數量都會變成 \(0\)
分析
#include<cstdio>
#include<algorithm>
const int maxn=15;
struct asd{
int num,id;
asd(){}
asd(int aa,int bb){
num=aa,id=bb;
}
}b[maxn];
bool cmp(asd aa,asd bb){
return aa.num<bb.num;
}
int n,cnt,sta[maxn],top;
int main(){
scanf("%d",&n);
int cs=1;
while(n){
b[++cnt]=asd(n%10,cs);
n/=10;
cs*=10;
}
std::sort(b+1,b+1+cnt,cmp);
int head=1;
while(head<=cnt){
int now=0;
while(b[head].num==0 && head<=cnt) head++;
for(int i=head+1;i<=cnt;i++){
now+=b[i].id;
b[i].num-=b[head].num;
}
now+=b[head].id;
for(int i=1;i<=b[head].num;i++){
sta[++top]=now;
}
b[head].num=0;
}
printf("%d\n",top);
for(int i=1;i<=top;i++){
printf("%d ",sta[i]);
}
printf("\n");
return 0;
}