题目
可以进行三种操作。一、将0变成1;二、将问号变成0或者1;三、交换两个字符;用最少的步骤将S串变成T串。不行就输出-1。
思路
本题从代码角度,无非四种行为:
- 交换两个非”?”且与目标态不同元素。
- 对于一个”?”k,再找一个非”?”元素i,i满足目标态与k不同,且i与目标态不同。将k变成i,并交换。
- 对于一个”?”,将其变为目标态。
- 对于一个与目标态不同且为”0”的,将其变为目标态。
此处,1一费两收益,2两费两收益,3和4一费一收益。并且2应尽早执行,因为在平均费相同的情况下,先3和4后2,可能会让答案出不来。
所以根据贪心思想,最后的顺序是:1,2,3/4。
另外需要注意的是,2时需双向扫描。
代码
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 100 + 10;
char S[maxn], T[maxn];
int ans, n;
int main() {
int t, kase = 0;
scanf("%d", &t);
while (t--) {
scanf("%s%s", S, T);
n = strlen(S);
ans = 0;
for (int i = 0; i<n; i++)
if (S[i] != '?' && S[i] != T[i])
for (int j = i+1; j<n; j++)
if (S[j] != '?' && S[j] != T[j] && S[j] != S[i]) {
swap(S[i], S[j]);
ans++;
break;
}
for (int i = 0; i<n; i++)
if (S[i] == '?')
for (int j = i+1; j<n; j++)
if (T[i] != T[j] && S[j] != T[j] && S[j] != '?') {
S[i] = T[i];
S[j] = T[j];
ans += 2;
break;
}
for (int i = n-1; i>=0; i--)
if (S[i] == '?')
for (int j = i-1; j>=0; j--)
if (T[i] != T[j] && S[j] != T[j] && S[j] != '?') {
S[i] = T[i];
S[j] = T[j];
ans += 2;
break;
}
for (int i = 0; i < n; i++)
if (S[i] == '?') {
S[i] = T[i];
ans++;
}
for (int i = 0; i<n; i++)
if (S[i] == '0' && S[i] != T[i]) {
S[i] = T[i];
ans++;
}
bool b = true;
for (int i = 0; i<n; i++)
if (S[i] != T[i]) {
b = false;
break;
}
if (b) printf("Case %d: %d\n", ++kase, ans);
else printf("Case %d: %d\n", ++kase, -1);
}
return 0;
}