题意:从一个二进制串中删除若干的字符,问最少删除几次才能使这个二进制小于所给的k。
思路:贪心。优先删除1,不够再删0。注意删1要从次高位开始。
cut and paste法证明:
完整代码:
#include<bits/stdc++.h>
#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define INF 0x3f3f3f3f
typedef long long ll;
const int maxn = 1e5+5;
using namespace std;
ll k;
int ans;
int mark[maxn];
char s[maxn];
ll fpow(ll base, ll n)
{
ll ans=1;
while(n)
{
if (n&1) ans*=base;
base*=base;
n>>=1;
}
return ans;
}
ll cal()
{
int top=0;
ll val=0;
for (int i=strlen(s+1); i>=1; i--)
{
if (mark[i]==1) continue;
val+=(s[i]-'0')*fpow(2,top);
top++;
}
return val;
}
void solve()
{
cin>>s+1;
if (cal()<=k) { cout<<0<<endl; return; }
for (int i=2; i<=strlen(s+1); i++)
{
if (s[i]=='1')
{
ans++;
mark[i]=1;
if (cal()<=k) { cout<<ans<<endl; return; }
}
}
for (int i=2; i<=strlen(s+1); i++)
{
if (mark[i]) continue;
ans++;
mark[i]=1;
if (cal()<=k) { cout<<ans<<endl; return; }
}
return;
}
int main()
{
FAST;
while(cin>>k)
{
solve();
}
return 0;
}