题目大意:可以进行三种操作。一、将0变成1;二、将问号变成0或者1;三、交换两个字符;用最少的步骤将S串变成T串。不行就输出-1。
思路:
输出-1情况只有一种,上面那行的0的个数+?的个数 <下面一行0的个数(或者可以用另一种方法,即s中数字1的个数大于t中数字1的个数)
首先把0上面的问号变成0;
因为把0上面的问号变成1之后,肯定需要一步交换;
而变成0之后,要么不需要操作了,要么多一步变成1;操作数只会少,不会多;
现在所有的问号都只存在于1的上面;
然后我们统计上下两个串中0的个数;
还有上面是0下面是1的错位个数;假如全部“?”都变了,那么上下0,1个数是相同的;那么错位数就是交换的操作数;如果上面0多;那么剩下的“?”就都是1;并且还有几个0要变成1;0变成1之后操作数多了1,错位少了1(操作数也少了1)所以不影响;答案还是前面统计出来的错位数;如果下面多那么“?”就要变成0,那么就多出几个错位,加上去就行;当然结果要加上“?”的个数,“?”都要变成0或1;
下面附上AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn =100+10;
char s[maxn],t[maxn];
int main()
{
int n;
cin>>n;
int i;
for(i=1;i<=n;i++)
{
cin>>s>>t;
cout<<"Case "<<i<<": ";
int s1=0,t1=0,q1=0,num=0;
int len=strlen(s);
for(int j=0;j<len;j++)
{
/*int ss=0,tt=0;
if(s[j]='1')
ss++;
if(t[j]=='1')
tt++;*/
if(t[j]=='0')
t1++;
if(s[j]=='0')
s1++;
if(s[j]=='?')
{
q1++;
num++;
}
if(s[j]=='?'&&t[j]=='0')
{
s[j]='0';
s1++;
q1--;
}
}
if(s1+q1<t1)
//if(ss>tt)
{
cout<<"-1"<<endl;
continue;
}
int sum =t1-s1;
int s0=0,s2=0;
for(int k=0;k<len;k++)
{
if(s[k]=='0'&&t[k]=='1')
s0++;
}
if(sum>0)
{
s0+=sum;
}
num+=s0;
cout<<num<<endl;
}
return 0;
}