CF1256F Equalizing Two Strings(冒泡排序、思维)
题意:
给出两个长度相同的字符串,询问能否通过每次翻转两个串相同长度的区间使得两个串一样。
题解:
/* *CF1256F *题意: *给定两个长度一样的仅有小写字母的字符串 *每次可以从两个串中分别选一个长度相等的子串进行翻转 *询问是否存在使两个串相等的操作方案 *题解: *首先每种字母的个数不同,直接NO *如果有某种字母出现次数超过2次,直接YES,可以将两个字母移动到一起后 *通过冒泡排序的方法无限次操作 *接下来只考虑每种字母只出现一次的情况 *冒泡排序每次能消除一次逆序对 *如果两者逆序奇偶性相同,只要小的那个在冒泡排序完成后不断浪费次数即可 *所以奇偶性相同YES *不相同NO */ #include<bits/stdc++.h> using namespace std; const int maxn=2e5+100; int t; int n; string s1,s2; int cnt[2][30]; int main () { cin>>t; while (t--) { int f=1; memset(cnt,0,sizeof(cnt)); cin>>n; cin>>s1; cin>>s2; for (int i=0;i<s1.size();i++) cnt[0][s1[i]-'a']++; for (int i=0;i<s2.size();i++) cnt[1][s2[i]-'a']++; for (int i=0;i<26;i++) if (cnt[0][i]!=cnt[1][i]) f=0; int f1=0; for (int i=0;i<26;i++) if (cnt[0][i]>1) { f1=1; } if (f==1&&f1==1) { printf("YES\n"); continue; } memset(cnt,0,sizeof(cnt)); int sum1=0,sum2=0; for (int i=0;i<n;i++) { int p=s1[i]-'a'; for (int j=p+1;j<26;j++) sum1+=cnt[0][j]; int p1=s2[i]-'a'; for (int j=p1+1;j<26;j++) sum2+=cnt[1][j]; cnt[0][p]++; cnt[1][p1]++; } if (sum1%2!=sum2%2) f=0; if (f) printf("YES\n"); else printf("NO\n"); } }