codeforce链接:http://codeforces.com/gym/102001/problem/L
vjudge链接:https://vjudge.net/problem/Gym-102001L
题意:给一个整数k和一个二进制数(不含前导0),问从二进制数中最少删去多少位,使得该数所转化成的十进制数小于等于k。
思路:
贪心。因为当前位上是1时的贡献永远比是0时要大,所以优先删去1。每删掉1位就与k比一次大小,若1都删完还不满足要求再删0.
注意:因为输出的数中也不含前导0,所以删去的时候第一位不用考虑。
贴上代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char s[100];
int flag[100];
long long quickmul(long long res,int ti)//快速幂
{
long long ans=1;
while(ti)
{
if(ti&1)
ans=ans*res;
res=res*res;
ti>>=1;
}
return ans;
}
int main()
{
long long k;
while(~scanf("%I64d",&k))
{
memset(flag,0,sizeof(flag));
scanf("%s",s);
int len=strlen(s),co=0;
long long mid=0;
for(int i=0;i<len;i++)
{
if(s[i]=='1')
{
flag[i]=1;
mid+=quickmul(2,len-i-1);
}
}
int nowl=len;
while(mid>k)
{
int i=1;
for(;i<len;i++)
{
if(flag[i]==1)
{
flag[i]=-1;
break;
}
}
mid=0;
nowl--;
if(i!=len)//除第一位之外还有1
{
int cnt=0;//当前位
for(int j=len-1;j>=0;j--)
{
if(flag[j]==1)
{
mid+=quickmul(2,cnt);
cnt++;
}
else if(flag[j]==0)
cnt++;
}
}
else
mid+=quickmul(2,nowl-1);
co++;
}
printf("%d\n",co);
}
return 0;
}