Linking
题意:
将一个数n,通过
2
k
2^k
2k 或者
−
2
k
-2^k
−2k 之和表示。问至少需要多少二次幂数?
n 通过二进制串 s 给出。
1
≤
∣
s
∣
≤
1
0
6
1 ≤ |s| ≤ 10^6
1 ≤ ∣s∣ ≤ 106.
思路:
- 如果有一位是单个1的话,那么直接用这一位表示的二次幂数加上。
- 如果有一段连续1的话,就相当于前面补个1表示的数-1所得,于是就可以用一次+1操作将这一串1变成最前面补的一个1。
这个1如果不能和其前面的1连到一起的话,可以用一个操作数将其消掉;
如果能和前面连到一起,那么这个操作数就省掉了。
所以整体思想就是将单个1直接消掉,连续的1往上进一位,变成单个1。
Code:
const int N = 2000010, mod = 1e9+7;
int T, n, m;
int a[N], f[N];
int main(){
string s;
getline(cin,s);
n=s.size();
s="0"+s;
for(int i=1;i<=n;i++) if(s[i]=='1') f[i]=1;
int cnt=0, ans=0;
for(int i=n;i>=1;i--)
{
if(s[i]=='1'&&s[i-1]=='1') f[i-1]+=f[i];
else if(s[i]=='1' && s[i-1]=='0')
{
if(f[i]==1) ans++;
else{
s[i-1]='1';
ans++;
f[i-1]=1;
}
}
}
if(s[0]=='1') ans++;
cout<<ans;
return 0;
}