题意:给出两个等长的字符串,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(因为下面的0是动不了的,无法再配对了),说明上面的1找不到与它配对的了,不存在
自己写的挫爆了(而且还是错的----)---网上看了好几篇题解的贪心也好繁琐
学习的这一篇 http://acm.lilingfei.com/uva-12545-bits-equalizer-%E4%B9%A0%E9%A2%988-3_98
好棒o(≧v≦)o~~
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #include<vector> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<algorithm> 11 using namespace std; 12 13 typedef long long LL; 14 const int INF = (1<<30)-1; 15 const int mod=1000000007; 16 const int maxn=1000005; 17 18 char s[maxn]; 19 char t[maxn]; 20 21 int main(){ 22 int T; 23 scanf("%d",&T); 24 int kase=0; 25 while(T--){ 26 cin>>s; 27 cin>>t; 28 29 int len=strlen(s); 30 int one_zero=0,zero_one=0,q_one=0,q_zero=0; 31 32 for(int i=0;i<len;i++){ 33 if(s[i]==‘1‘&&t[i]==‘0‘) one_zero++; 34 if(s[i]==‘0‘&&t[i]==‘1‘) zero_one++; 35 if(s[i]==‘?‘&&t[i]==‘1‘) q_one++; 36 if(s[i]==‘?‘&&t[i]==‘0‘) q_zero++; 37 } 38 39 int ans=0; 40 while(one_zero&&zero_one){ 41 ans++; 42 one_zero--; 43 zero_one--; 44 } 45 while(one_zero&&q_one){ 46 ans+=2; 47 one_zero--; 48 q_one--; 49 50 } 51 52 if(one_zero) ans=-1; 53 else ans+=zero_one+q_one+q_zero; 54 55 printf("Case %d: %d\n",++kase,ans); 56 } 57 return 0; 58 }
时间: 2024-10-26 03:49:30