[2020 年百度之星·程序设计大赛 - 复赛] Battle for Wosneth

题解

+1会把前面所有1变成0,第一个0变成1,也就是批量消除前缀1,显然他只会用一次,
枚举时机就好了

如果a[i]是0,次数为a[0 ~ i-1]中0的个数+b[0 ~ i-1]中1的个数+1(+1次数)+后面常规替换次数,如果b[i]=0还要把a[i]变一次
如果a[i]是1 花一次机会把a[i]变成0 同上.

代码

#include 
#include 
#include 
using namespace std;

int a[100010],b[100010];
int d[100010];
int n;

int main()
{
    int T;
    scanf("%d",&T);
    for (int tp = 1; tp <= T; tp++) {
        scanf("%d",&n);
        //a->b
        for (int i = 0; i <= n+10; i++)  {
            d[i] = 0;
            a[i] = b[i] = 0;
        }
        for (int i = 1; i <= n; i++) {
            char c = getchar();
            while (c!='0' && c!='1') {
                c = getchar();
            }
            if(c=='0') a[i] = 0;
            else a[i] = 1;
        }
        for (int i = 1; i <= n; i++) {
            char c = getchar();
            while (c!='0' && c!='1') {
                c = getchar();
            }
            if(c=='0') b[i] = 0;
            else b[i] = 1;
        }
        int a0 = 0,b1 = 0;
        a[n+1] = 0;
        b[n+1] = 0;
        d[n+1] = d[n+2] = 0;
        //cout<<(a+1);
        for (int i = n; i >= 1; i--)
            if (a[i] == b[i])
                d[i] = d[i+1];
            else
                d[i] = d[i+1]+1;
        int ans = d[1];
        for (int i = 1; i <= n+1; i++) {
            if (a[i] == 0) {
                int tmp = a0+b1+1+d[i+1];
                if (b[i] == 0) tmp++;
                ans = min(ans, tmp);
            } else {
                int tmp = a0+b1+1+1+d[i+1];
                if (b[i] == 0) tmp++;
                ans = min(ans, tmp);
            }
            if (a[i] == 0) a0++;
            if (b[i] == 1) b1++;
        }

        cout<<ans<<endl;

    }
    return 0;
}

Problem Description

你有两个无限长01串S,T,分别记作S0S1…和T0T1…。其中S和T从n位之后都是0,也就是当i≥n,有Si=Ti=0。

你可以对S串进行操作:

  • 修改S串的某一位,从0变成1或者从1变成0。
  • 将S当成二进制数加1,也就是记s=∑i≥0Si2i,将S变成s+1二进制表示的形式,其中低位在最前面。

问最少的步数将S变成T。

Input
第一行一个正整数T(1≤T≤104)表示数据组数。

对于每组数据,第一行一个整数n,接下来两行长度为n(1≤n≤105)的01串S和T,表示S和T的前n位。

保证∑n≤106。

Output
对于每组数据,输出一个整数,表示步数。

Sample Input

3
5
11111
00000
5
10100
01010
5
00000
00001

Sample Output

2
3
1

Hint

第一组数据中,可以选择先加一变成 “000001”,然后将S5变成 ‘0’。

第二组数据中,先加一变为 “01100”,然后直接修改。

第三组数据中,直接修改。

你可能感兴趣的:(OI/ACM,Solution)