D. Two Strings Swaps
容易发现,a[i], a[n-i+1], b[i], b[n-i+1] 可以互相交换,且不会受其他地方影响,关键在于对于这4个字符怎们计算最小的操作数,讨论到死。。。看了别人的代码,用不同的字符对数表示字符的组成,就比较容易判断了。还不太清楚是如何想到的。。。只会写暴力枚举本质不同的这种正方形。。
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
typedef long long ll;
const int N = 2e5 + 7;
using namespace std;
int n,ans,num[366];
char s1[N],s2[N];
int cal(string s1,string s2) {
if(s1==s2)return 0;
if(s1[0]==s1[1]&&s2[0]==s2[1]) return 0;
string t=s1; t+=s2;
int d=0;
for(int i=0;i<4;++i)
for(int j=0;j<i;++j) if(t[i]!=t[j])++d;
int ans=0;
if(d==3) ++ans;
else if(d==5&&s1[0]==s1[1]) ans+=2;
else if(d==5&&s1[0]!=s1[1]) ans++;
else if(d==6) ans+=2;
return ans;
}
//int id[111],M[N];
//int ck(int a,int b,int c,int d) {
// memset(id,0,sizeof(id));
// int cc=0;
// if(!id[a])id[a] = ++cc;
// if(!id[b])id[b] = ++cc;
// if(!id[c])id[c] = ++cc;
// if(!id[d])id[d] = ++cc;
// int t = id[a]*10000 + id[b]*1000 + id[c]*100 + id[d];
// return !M[t];
//}
//void biao(int a,int b,int c,int d) {
// memset(id,0,sizeof(id));
// int cc=0;
// if(!id[a])id[a] = ++cc;
// if(!id[b])id[b] = ++cc;
// if(!id[c])id[c] = ++cc;
// if(!id[d])id[d] = ++cc;
//
// int t = id[a]*10000 + id[b]*1000 + id[c]*100 + id[d];
// M[t] = 1;
//}
int main() {
// for(int i=0;i<4;++i)
// for(int i1=0;i1<4;++i1)
// for(int i2=0;i2<4;++i2)
// for(int i3=0;i3<4;++i3) {
// if(ck(i,i1,i2,i3)){
// printf("%d %d
",i,i1);
// printf("%d %d
",i2,i3);
// biao(i,i1,i2,i3);
// }
// }
scanf("%d",&n);
scanf(" %s",s1+1);
scanf(" %s",s2+1);
if(n%2==0) {
for(int i=1;i<=n/2;++i) {
int p = n - i + 1;
string t1,t2;
t1+=s1[i];t1+=s1[p];t2+=s2[i];t2+=s2[p];
sort(t1.begin(),t1.end());
sort(t2.begin(),t2.end());
ans += cal(t1,t2);
}
}
else {
for(int i=1;i<=n/2;++i) {
int p = n - i + 1;
string t1,t2;
t1+=s1[i];t1+=s1[p];t2+=s2[i];t2+=s2[p];
sort(t1.begin(),t1.end());
sort(t2.begin(),t2.end());
ans += cal(t1,t2);
}
if(s1[n/2+1]!=s2[n/2+1])++ans;
}
printf("%d
",ans);
return 0;
}