UVa 12545 Bits Equalizer (贪心)

题意:给出两个等长的字符串,0可以变成1,?可以变成0和1,可以任意交换s中任意两个字符的位置,问从s变成t至少需要多少次操作。

析:先说我的思路,我看到这应该是贪心,首先,如果先判断s能不能变成t,就计算t中的1和s中的1。

然后算出t比s多多少1,然后先考虑把?变成1是最优的,如果不够就只能把0变成1,切不可把?变成1,因为这样要两步,

不是最优,而把0变成1是一步。然后把剩下的?变成1(如果1还不够)或者是0(1够了)。最后是计算要交换的次数,

这个只要统计不同的位置有多少即可,别忘了1可能还不够,这个也要算上,怎么算呢,想一下,先把0变成1,再交换,

所以说是要先加上要变化的1,然后在不同位置中也加上,然后除以2.相加就是结果。

然而我觉得自己写的太烂了,上网百度,看到大神们写的就是简洁明了。。。。

是这么想的,首先交换是最优的,因为一次操作能满足两个,然后再去找1-0和?-1的进行交换,为什么呢?因为我们看s中的1是不是多了,

如果少,没关系,可以直接把?变成1,如果多了就无解了,所以要比较这个。最后再加上?-0即可,这个只要一步。

大神就是牛逼。

代码如下:

这是我的代码

#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;
const int maxn = 100 + 10;
char s[maxn], t[maxn];

int main(){
//    freopen("in.txt", "r", stdin);
    int T;    cin >> T;
    for(int kase = 1; kase <= T; ++kase){
        scanf("%s %s", s, t);
        int n = strlen(s);
        int cnts1 = 0, cntt0 = 0, cnts0 = 0;//cnts1是s串中1的个数,同理其他的
        for(int i = 0; i < n; ++i){
            if(‘0‘ == t[i])   ++cntt0;
            if(‘0‘ == s[i])   ++cnts0;
            else if(‘1‘ == s[i])  ++cnts1;
        }
        int cntt1 = n - cntt0;//1的个数
        int cntss = n - cnts0 - cnts1;//?的个数
        int det = cntt1 - cnts1;//s和t差多少1

        printf("Case %d: ", kase);
        if(det < 0){  printf("-1\n"); continue; }//1太多了,把问号全改了都不够

        int cnt = 0;
        for(int i = 0; i < n; ++i)
            if(det && ‘?‘ == s[i] && t[i] == ‘1‘){
                ++cnt;  s[i] = ‘1‘; --det;//把?变成1
            }

        for(int i = 0; i < n; ++i)//把0变成1
            if(det && ‘0‘ == s[i] && ‘1‘ == t[i]){
                --det;  s[i] = ‘1‘;  ++cnt;
            }

        for(int i = 0; i < n; ++i){//把剩下的?变成0或1
            if(det && ‘?‘ == s[i]){  ++cnt;  s[i] = ‘1‘;  --det; }
            if(!det && ‘?‘ == s[i]){  ++cnt;  s[i] = ‘0‘;  }
        }

        int x = 0;
        for(int i = 0; i < n; ++i)//计算不同的数,
            if(s[i] != t[i]) ++x;

        cnt += det;//计算要要交换的次数
        cnt += (x + det)/ 2;
        printf("%d\n", cnt);
    }
    return 0;
}

下面是我参考大神们的代码写的:

#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;
const int maxn = 100 + 10;
char s[maxn], t[maxn];

int main(){
    int T;    cin >> T;
    for(int kase = 1; kase <= T; ++kase){
        scanf("%s %s", s, t);
        int n = strlen(s);
        int zero_one = 0, one_zero = 0, q_one = 0, q_zero = 0;

        for(int i = 0; i < n; ++i){
            if(s[i] == ‘0‘ && t[i] == ‘1‘)  ++zero_one;
            else if(s[i] == ‘1‘ && t[i] == ‘0‘)  ++one_zero;
            else if(s[i] == ‘?‘ && t[i] == ‘0‘)  ++q_zero;
            else if(s[i] == ‘?‘ && t[i] == ‘1‘)  ++q_one;
        }

        int cnt = 0;
        while(zero_one && one_zero){
            --zero_one;   --one_zero;
            ++cnt;
        }

        while(q_one && one_zero){
            --q_one;   --one_zero;
            cnt += 2;
        }

        if(one_zero)  cnt = -1;
        else  cnt += q_zero + zero_one + q_one;

        printf("Case %d: %d\n", kase, cnt);
    }
    return 0;
}
时间: 2024-08-06 17:08:46

UVa 12545 Bits Equalizer (贪心)的相关文章

uva 12545 - Bits Equalizer(比特变化器)

好在原来做题的思路不知道何时就养成了这种思路,可能是见这种思路多了一点吧,就自然的想到了用这种方法. 没有什么原因,思路题么,有思路那还用多说些什么,而思路是怎么来的,就更没什么好说的了...多去体会大神的思路或许是我等菜鸟提高的一个途径吧 #include<cstdio> #include<cstring> #include<string> #include<iostream> using namespace std; string s1,s2; int

UVa 12545 Bits Equalizer【贪心】

题意:给出两个等长的字符串,0可以变成1,?可以变成0和1,可以任意交换s中任意两个字符的位置,问从s变成t至少需要多少次操作 先可以画个草图 发现需要考虑的就是 1---0 0---1 ?---0 ?---1 下面三种都是只需要一次操作就可以完成的, 所以应该优先考虑1---0 如果存在0---1,就优先交换1---0和0---1,因为这样可以同时满足两组 如果不存在0---1,就交换1---0与?---1,这样每交换一次,需要两次操作,即先将问号变成0,再交换 如果最后都还剩下有1--0(因

UVA - 12545 Bits Equalizer (比特变换器)(贪心)

题意:输入两个等长(长度不超过100)的串S和T,其中S包含字符0,1,?,但T只包含0和1,你的任务是用尽量少的步数把S变成T.有以下3种操作: 1.把S中的0变成1. 2.把S中的"?"变成0或1. 3.交换S中任意两个字符. 分析: 1.为保证步数最少,先统计两串中1的个数和1的位置.如果cnta>cntb,则不能把S变成T,因为1不能变成0. 2.先将?变成0或1,变换原则是若cnta<cntb且b中对应位置为1,则变为1:否则,变为0. 3.再将0变成1,变换原则

UVA 12545 Bits Equalizer

#include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=1000100; const int INF=1<<29; char s[maxn],t[maxn]; int len; int c10,c01,c1,c0;

12545 - Bits Equalizer(贪心?)

这道题我是自己出的思路,一遍A的 ,0.000ms. 看网上的题解大多相仿,我就说说我的思路吧 . 假设字符串 a.b 我们只需要从前向后扫一遍就行了,遇到?跳过去,遇到a[i] = '0'&&a[i]!=b[i] ;那么就向后找一个a[j]=='1'&&a[i]!=b[j],也就是说先用交换这个技能比较省步骤 .如果没有可以交换的,再扫一遍找? 如果a[i]==? && b[i]==0  那么显然可以先将?变成1 再和a[i]交换  ,需要两步,如果仍然没

UVa12545 Bits Equalizer (贪心)

链接:http://bak2.vjudge.net/problem/UVA-12545 分析:贪心乱搞. 1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 5 const int maxn = 100 + 5; 6 7 char s[maxn], t[maxn]; 8 9 int main() { 10 int T; 11 scanf("%d", &T); 12 for (

UVA 10317 - Equating Equations 贪心 dfs

UVA 10317 - Equating Equations 贪心 dfs ACM 题目地址:UVA 10317 - Equating Equations 题意: 给一个等式,但是这个等式不一定是正确的,要你对等式中的数字重新排序,使得等式成立.等式只有+和-,数字个数小于16. 分析: 以a + b - c = d - e为例子. 1. 我们把等式右边的各项都换到左边,a + b - c - d + e = 0 2. 把+项和-项放一起,就变成(a + b + e) - (c + d) = 0

UVA 12130 - Summits(BFS+贪心)

UVA 12130 - Summits 题目链接 题意:给定一个h * w的图,每个位置有一个值,现在要求出这个图上的峰顶有多少个.峰顶是这样定义的,有一个d值,如果一个位置是峰顶,那么它不能走到不大于该峰顶高度 - d的位置,如果满足这个条件下,并且无法走到更高的山峰,那么它就是峰顶 思路:利用贪心的策略,把所有点丢到优先队列,每次取出最高的峰值开始找,进行广搜,搜的过程中记录下最大值的点的个数,如果这个是峰顶,就加上这个数.判断是不是峰顶的方法为,如果广搜过程中,不会找到一个点的能到的最高峰

uva 1534 - Taekwondo(dp+贪心)

题目连接:uva 1534 - Taekwondo 题目大意:有两组什么东西,题目背景有点忘记了,就是给出两组数,两组个数分别为n,m,要求找出min(n,m)对数,每个数最多最多选一次,使得这min(n,m)对数ai,bi,ai-bi的绝对值之和最小. 解题思路:贪心,将两组数分别排序,然后dp[i][j]表示i对,匹配到j时候的最优解. #include <cstdio> #include <cstring> #include <cmath> #include &l