[51Nod](1413)权势二进制(Codeforces Round #300 B. Quasi Binary) ---- 思维+贪心

一个十进制整数被叫做权势二进制,当他的十进制表示的时候只由0或1组成。例如0,1,101,110011都是权势二进制而2,12,900不是。

当给定一个n的时候,计算一下最少要多少个权势二进制相加才能得到n。

Input

单组测试数据。
第一行给出一个整数n (1<=n<=1,000,000)

Output

输出答案占一行。

Input示例

9

Output示例

9

思路: 一开始想的是把1000000以内的所有权势二进制数打表预处理,然后二分+贪心去做。结果发现这个思路有问题。因为这样局部最优,并不是全局最优,也不是最优解。只能过部分数据。

错误代码: 主要记录一下bitset和c_str()第一次使用的记录 233333
这里写图片描述

#include <bits/stdc++.h>
using namespace std;
int ch[105];
int main()
{
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    #endif //LOCAL
    ios_base::sync_with_stdio(false);
    cin.tie(NULL),cout.tie(NULL);
    for(int i=0;i<=64;i++)//打表预处理
    {
        bitset<8>a(i);
        string str = a.to_string();
        ch[i]= atoi(str.c_str());
    }
    for(int i=0;i<=64;i++)
        cout<<ch[i]<<endl;
    int n;
    cin>>n;
    int ans = 0;
    while(n)
    {
        int pos = upper_bound(ch,ch+65,n)-ch;
        pos--;
        int tmp = n/ch[pos];
        ans += tmp;
        n = n-tmp*ch[pos];
    }
    cout<<ans<<endl;
    return 0;
}

到后来发现~~~~
9 由9个1 组成 总计为9
3 2 由2个11 和 1个10组成 总计为3
9 9 8 由 8个 111 和 1个110 组成 总计为9

发现到最终答案就是n中最大的那一位数 (思维题,好有意思)

AC代码:
51Nod

#include <bits/stdc++.h>
using namespace std;
int main()
{
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    #endif //LOCAL
    ios_base::sync_with_stdio(false);
    cin.tie(NULL),cout.tie(NULL);
    int n;
    cin>>n;
    int maxn = -1;
    while(n)
    {
        int tmp = n%10;
        maxn = max(tmp,maxn);
        n/=10;
    }
    cout<<maxn<<endl;
    return 0;
}

CodeForce的输入输出

input

9

output

9
1 1 1 1 1 1 1 1 1

input

32

output

3
10 11 11
思路: codeforces要求把这些组成的权势二进制也要从大到小输出,所以要利用贪心,看看n的每一位是不是大于0,如果大于零那么对应位的权势二进制数就要置1保证减去这次该减去的,这样才可以得到最优解。否则就置0

AC代码:
Codeforces:

#include <bits/stdc++.h>
using namespace std;
int a[105];
int main()
{
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    #endif //LOCAL
    ios_base::sync_with_stdio(false);
    cin.tie(NULL),cout.tie(NULL);
    int n;
    int maxn = -1;
    cin>>n;
    int i = 0;
    while(n)
    {
        a[i] = n%10;
        maxn = max(maxn,a[i]);
        n/=10;
        i++;
    }
    reverse(a,a+i);
    int nn,ans;
    nn = i;
    ans = maxn;
    cout<<ans<<endl;
    int tmp = 0;
    for(int i=0;i<maxn;i++)
    {
        tmp = 0;
        for(int j=0;j<nn;j++)
        {
            if(a[j]>0)
            {
                tmp = tmp*10+1;
                a[j]--;
            }
            else
                tmp = tmp*10;
        }
        ans-=tmp;
        cout<<tmp<<" ";
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值