Bits Equalizer UVA - 12545 解题报告

版权声明:大鹏专属 https://blog.csdn.net/NCC__dapeng/article/details/88379885

题目大意:给你两个串,S,T,S串包括0,1,?,但T中只包含1,0,你的任务是用最小的步骤把S变为T。

你可以对S进行三种操作:

1、将?变为1 or 0.

2、将0变为1.

3、0,1互相交换位置。

思路:一开始感觉这是一道贪心题,目的就是让你制定一个规则,然后在这个规则下,能使进行的步骤最少。

一开始就在按照自己的思想进行模拟,但最后发现这个方法很不好实现,去网上搜了搜其他大佬的发现,这道题被硬生生的变成了思维和数学题。

我的思路:按部就班,判断?的个数以及转变,然后寻找交换,变换的位置,复杂度≈ ∞,思维度0

大佬的思路:思维问题,问号都要转换的,还可以让1变为0,然后与0变为1的部分进行抵消,然后AC,复杂度0,思维度10。

我:。。。卑微

下面来具体介绍一下大佬的操作,?必须要转换,所以最基础的操作步骤就是?的个数,然后我们假设1可以变换为0,这是违法操作,但是可以与0变为1的部分进行抵消,抵消意味着只要两个位置进行交换就可以了。

然后下面重点解释一下,我们如何判断非法的情况,非法的条件很容易知道,就是S串的0比T串的0少,那么就是非法的,首先我们先将上面说的1->0,0->1部分进行抵消,如果1->0还有剩余,此时意味着?->1的个数过多,我们在与?->1进行比较,如果还有剩余证明非法。

下面给出AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1000+100;
const int INF=0x3f3f3f3f;
char s[maxn];
char c[maxn];

int main()
{
    //ios::sync_with_stdio(false);
    int T;
    scanf("%d",&T);
    for(int kase=1; kase<=T; kase++)
    {
        scanf("%s %s",s,c);
        int len=strlen(s),sq_1=0,sq_0=0,s1_c0=0,s0_c1=0,ans=0,cnt=0;
        for(int i=0; i<len; i++)
        {
            if(s[i]=='?'&&c[i]=='1') ans++,sq_1++;
            else if(s[i]=='?'&&c[i]=='0') ans++,sq_0++;
            else if(s[i]=='1'&&c[i]=='0') ans++,s1_c0++;
            else if(s[i]=='0'&&c[i]=='1') ans++,s0_c1++;
        }
        //以上过程进行完毕后,S=T但所经历的过程并不是最简单的.

        int neu=min(s1_c0,s0_c1);//首先抵消可交换的情况
        cnt+=neu,s1_c0-=neu,ans-=neu*2;//cnt代表交换所需要进行的步骤,此时总步数需要减去0->1,1->0中的公共部分所以要乘2

        neu=min(sq_1,s1_c0);//判断?->1与1->0,此时cnt代表将?->0并且0,1互换位置的过程,总步数需要减去?->1的过程与1->0的过程。
        cnt+=neu*2,s1_c0-=neu,ans-=neu*2;

        if(s1_c0) printf("Case %d: -1\n",kase);
        else printf("Case %d: %d\n",kase,ans+cnt);



    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/NCC__dapeng/article/details/88379885
今日推荐