二进制难题
一个十进制整数被叫做权势二进制,当他的十进制表示的时候只由0或1组成。例如0,1,101,110011都是权势二进制而2,12,900不是。
当给定一个n的时候,计算一下最少要多少个权势二进制相加才能得到n。
Input单组测试数据。
第一行给出一个整数n (1<=n<=1,000,000)Output输出答案占一行。
Sample Input
9
Sample Output
9
题目分析 :这道题其实有两种解法,且都不难。一是模拟,二是数学分析。
模拟:我们想,如果想尽可能的小,那每次加的就要尽可能的大,即每一位都为1.但我们要考虑有多少个1呢?比如110276,第一个最大的数是110111,
剩余的数是165.第二个最大的数是111,剩余54。第三个11,剩余43。依次知道为10.这要记录加了几次就可以了;
AC代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
const int maxn = 10;
using namespace std;
int num[maxn],sum;
bool op;
string s;
void init()
{
for (int i = 0; i < s.size(); i++)
num[i] = s[i] - '0';
}
void update(int x, int y)
{
sum++;
int start = 0, mid = 0;
for (int i = x; i < y; i++)
{
if (num[i] != 0 && num[i] != 1)
start = 1, op = true;
else
num[i] = 0;
if (start)
{
if (num[i] == 0)
num[i] = 0;
else
num[i] = num[i] - 1;
mid++;
}
}
if (start)
update(y - mid, y);
}
int main()
{
//freopen("in.txt", "r", stdin);
while (cin >> s)
{
init();
sum = 0;
op = false;
update(0, s.size());
if (!op)
{
if (s == "0")
printf("0\n");
else
printf("1\n");
}
else
printf("%d\n", sum);
}
return 0;
}
数学分析:9998这个数,由8个1111,和1个1110构成。49985,由4个11111,1个1111,3个1110,1个1100构成。我们发现,它的每一位无非由1和0构成,所以它要想把每一位填满,就必须有足够的1.
而已经别填满的位置就由0来填,如此我们只需求每个位最大的值即可!
#include <iostream> #include <algorithm> #include <cstdio> #include <string> const int maxn = 10; using namespace std; int num[maxn]; string s; void init() { for (int i = 0; i < s.size(); i++) num[i] = s[i] - '0'; } int main() { //freopen("in.txt", "r", stdin); while (cin >> s) { int ans = 0; init(); for (int i = 0; i < s.size(); i++) ans = max(ans, num[i]); printf("%d\n", ans); } return 0; }