UVa:12545 Bits Equalizer(贪心)
2015-08-22 17:24
204 查看
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=845&page=show_problem&problem=3990
题意:输入两个等长(长度不超过100)的串S和T,其中S包含字符0,1,?,但T只包含0和1。你的任务是用尽量少的步数把S变成T。每步有3种操作:把S中的0变成1;把S中的“?”变成0或者1;交换S中任意两个字符。例如:01??00经过3步可以变成001010(方法是先把两个问号变成1和0,再交换两个字符)。(本段摘自《算法竞赛入门经典(第2版)》)
分析:
直觉是采用贪心。策略如下:由于S中0可以转换成1,而1不能转换成0,所以首先统计S中?和1的个数cnt1,以及T中0的个数cnt2,如果cnt1小于cnt2,很明显无法转化成功,直接输出-1。其他情况都可以转化成功。
对于可以转换的情况,从贪心的角度来看,将S中的两个字符交换位置最多可以使2个字符到达正确位置,而其他操作只能有一个,因此优先考虑此操作。由于S和T中位置相同且字符也相同的不需要转换,因此只考虑不相同的。设S中0的个数为x,1的个数为y,?的个数为z,T中与S的1对应的0的个数为xx,与S中0对应的1的个数为yy,与S中?对应的0和1的个数分别为xxx和yyy。
如果x≥yx\ge y,则多出的0对应1可以由0直接转换成1,?也可以直接转化,ans=min(x,y)+max(x,y)−min(x,y)+cntans = min(x, y) + max(x, y) - min(x, y) + cnt(其中cnt为S中?的个数)。化简得ans=max(x,y)+cntans = max(x, y) + cnt。
如果x≤yx\le y,则多出的1可以和?对应1的地方进行互换,关键在于证明?中所对应1个数大于等于S中剩下1的个数。证明如下:由于S中0对应1的地方已经被换完了,所以假设x=0x = 0,则有题意和以上假设可得y+z=xx+xxx+yyy,z≥xx+xxxy + z = xx + xxx + yyy, z \ge xx + xxx,需证yyy≥yyyy \ge y,将已知条件合并即可得到结论。则ans=min(x,y)+max(x,y)−min(x,y)+cntans = min(x, y) + max(x, y) - min(x, y) + cnt。化简得ans=max(x,y)+cntans = max(x, y) + cnt。
综上,两种情况的结果是统一的,ans=max(x,y)+cntans = max(x, y) + cnt。
代码:
题意:输入两个等长(长度不超过100)的串S和T,其中S包含字符0,1,?,但T只包含0和1。你的任务是用尽量少的步数把S变成T。每步有3种操作:把S中的0变成1;把S中的“?”变成0或者1;交换S中任意两个字符。例如:01??00经过3步可以变成001010(方法是先把两个问号变成1和0,再交换两个字符)。(本段摘自《算法竞赛入门经典(第2版)》)
分析:
直觉是采用贪心。策略如下:由于S中0可以转换成1,而1不能转换成0,所以首先统计S中?和1的个数cnt1,以及T中0的个数cnt2,如果cnt1小于cnt2,很明显无法转化成功,直接输出-1。其他情况都可以转化成功。
对于可以转换的情况,从贪心的角度来看,将S中的两个字符交换位置最多可以使2个字符到达正确位置,而其他操作只能有一个,因此优先考虑此操作。由于S和T中位置相同且字符也相同的不需要转换,因此只考虑不相同的。设S中0的个数为x,1的个数为y,?的个数为z,T中与S的1对应的0的个数为xx,与S中0对应的1的个数为yy,与S中?对应的0和1的个数分别为xxx和yyy。
如果x≥yx\ge y,则多出的0对应1可以由0直接转换成1,?也可以直接转化,ans=min(x,y)+max(x,y)−min(x,y)+cntans = min(x, y) + max(x, y) - min(x, y) + cnt(其中cnt为S中?的个数)。化简得ans=max(x,y)+cntans = max(x, y) + cnt。
如果x≤yx\le y,则多出的1可以和?对应1的地方进行互换,关键在于证明?中所对应1个数大于等于S中剩下1的个数。证明如下:由于S中0对应1的地方已经被换完了,所以假设x=0x = 0,则有题意和以上假设可得y+z=xx+xxx+yyy,z≥xx+xxxy + z = xx + xxx + yyy, z \ge xx + xxx,需证yyy≥yyyy \ge y,将已知条件合并即可得到结论。则ans=min(x,y)+max(x,y)−min(x,y)+cntans = min(x, y) + max(x, y) - min(x, y) + cnt。化简得ans=max(x,y)+cntans = max(x, y) + cnt。
综上,两种情况的结果是统一的,ans=max(x,y)+cntans = max(x, y) + cnt。
代码:
#include <iostream> #include <fstream> #include <cstring> #include <vector> #include <queue> #include <cmath> #include <algorithm> #include <set> #include <string> using namespace std; const int maxn = 1005; int T, ans, cnt, cnt1, cnt2, x, y, l; string s, t; int main() { scanf("%d", &T); for (int C = 0; C < T; ++C) { ans = 0; cnt = 0; cnt1 = 0; cnt2 = 0; x = 0; y = 0; cin >> s >> t; l = s.size(); for (int i = 0;i < l; ++i) { if (s[i] == '?') ++cnt; if (s[i] != '1') ++cnt1; if (t[i] == '0') ++cnt2; if (s[i] == '0' && t[i] == '1') ++x; if (s[i] == '1' && t[i] == '0') ++y; } if (cnt1 < cnt2) ans = -1; else ans = max(x, y) + cnt; printf("Case %d: %d\n", C + 1, ans); } return 0; }
相关文章推荐
- HDU2050 折线分割平面 (线段数学规律)
- php DES加密算法
- socket编程--close、shutdown
- VS打包部署图文详细步骤及程序防卸载的制作(密码验证卸载)
- CSDN 下各种不同代码风格样例测试
- Hibernate入门
- 阿里巴巴校招
- hdu5410 CRB and His Birthday
- Java实现二叉树重构
- 04.第一个OC程序解析
- Python中的装饰器和函数式
- 引水数据--紧凑
- DOM解析XML
- O2O平台盈利模式有哪些
- SP800-53实现安全分级
- WebDriver使用IE和chrome浏览器
- 玛丽卡 (codevs p1021;洛谷p1186)
- 03.第一个OC程序
- 例说linux内核与应用数据通信(三):读写内核设备驱动文件
- SOA概念解惑