洛谷2320 bzoj1192 鬼谷子的钱袋

题目链接

题意概述:把正整数n分为m个正整数,m个正整数中不允许出现复数个非1的正整数,保证所有小于n的正整数都可以用一部分正整数的和表示,并且使m尽量小。

这道题不知道为啥bzoj上没有要求输出方案,导致我把bzoj的程序粘到洛谷上瞬间全wa。

思想还是非常简单的,第一个钱袋装n/2个金币,第二个装n/2/2个金币,第三个……

这样可以用和的形式表示任意小于n的正整数。

显然这样是最优解,而且基于不断除2得出的答案个数为log2n。

#include<cstring>
#include<iostream>
#include<cctype>
#include<cstdio>
#include<algorithm>
using namespace std;
inline int read()
{
    register int X=0;register char ch=0;
    for(;!isdigit(ch);ch=getchar());
    for(;isdigit(ch);ch=getchar()) X=(X<<3)+(X<<1)+ch-'0';
    return X;
}
inline void write(int x)
{
     if(x>9) write(x/10);
     putchar(x%10+'0');
}
int n,ans,b[100],m;
int main()
{
    n=read();
    m=n;
    while(m>>=1) ans++;
    m=ans+1,ans=0;
    while(n)
    { 
        b[m-(++ans)]=(n&1 ? (n>>1)+1 : n>>1);
        n>>=1; 
    }
    write(ans),putchar('
');
    for(int i=0;i<ans;i++) write(b[i]),putchar(' ');
}
原文地址:https://www.cnblogs.com/mordor/p/9566950.html