分析
明显的贪心题。
这道题我们只要知道 a a a、 b b b 两个字符串不同的字符的个数(后面用 c n t cnt cnt 代替)就可以解题了。
对于 c n t cnt cnt 的不同的值,会有以下 4 4 4 种情况:
- c n t = 0 cnt=0 cnt=0
- c n t cnt cnt 是奇数
- c n t = 2 cnt=2 cnt=2
- c n t ≥ 3 cnt\ge3 cnt≥3
这 4 4 4 种情况又分别对应着以下 4 4 4 种答案:
- 0 0 0,应为此时 a a a 与 b b b 初始就相等了
- − 1 -1 −1,应为当 c n t cnt cnt 为奇数时,无论操作多少次, a a a 与 b b b 都不可能相等
-
x
x
x、
y
y
y 或
2
×
y
2\times y
2×y,此时有两种情况:
- 两个不同的字符不相邻:直接交换,代价为 y y y
- 两个不同的字符相邻:有两种情况:
- 直接交换:代价为 x x x
- 分别与一个相同的字符进行交换:代价为 2 × y 2\times y 2×y
- c n t × y 2 \displaystyle\frac{cnt\times y}{2} 2cnt×y,应为根据题目可知 x ≥ y x\ge y x≥y,所以要尽量选择不相邻的两个字符取反;由于每次取反是取反两个字符,所以要去反 c n t 2 \displaystyle\frac{cnt}{2} 2cnt 次,而每次要消耗的代价为 y y y,故总代价为 c n t × y 2 \displaystyle\frac{cnt\times y}{2} 2cnt×y
所以只需要判断 c n t cnt cnt 属于以上那种情况再进行对应的操作即可。
注意:要开 long long
!
code
#include<iostream>
#define ll long long
using namespace std;
int loction[3005],t;
int main() {
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>t;
while(t--) {
ll len,x,y,cnt=0;
string a,b;
cin>>len>>x>>y>>a>>b;
for(int i=0;i<len;i++) if(a[i]!=b[i]) loction[++cnt]=i;//统计不同字符的位置
if(cnt==0) cout<<"0\n";//第一种情况
else {
if(cnt%2==1) cout<<"-1\n";//第二种情况
else if(cnt==2) {//第三种情况
if(loction[1]+1!=loction[2]) cout<<y<<"\n";
else cout<<min(x,2*y)<<"\n";
}else cout<<cnt/2*y<<"\n";//第四种情况
}
}
return 0;
}