链接:
http://codeforces.com/contest/1243/problem/B2
题目大意:
两个字符串,判断能否通过交换为从而使得这两个字符串完全一致,如不可以的话,直接输出NO,可以的话输出YES,并且输出每一步的交换位置。
思路:如果没个字符出现的次数为偶数次的话,那么一定可以成功,否则的话一定是NO。
如果说S[i]!=T[i],假如说,S中有与T[i]相同的元素,那么直接交换就可以了,操作次数为1,在T中找S[i]操作相同。
S中没有与T[i]相同的元素,我们保证了每个元素出先的次数为偶数次,那么在T中一定会有一个元素,我们只需要把在T中找一下S[i],然后将其与S中的某个元素交换一下,然后就变成了第一种情况,操作次数为2
所以如果可以的,我们最多操作2*n次。
#include<bits/stdc++.h> using namespace std; const int N=100; struct stu{ char a; int x1; }s1[N],t1[N]; int ar[N],br[N]; int arr[N]; void solve(){ memset(arr,0,sizeof arr); int n; cin>>n; string s,t; cin>>s>>t; for(int i=0;i<n;i++){ arr[s[i]-'a']++; arr[t[i]-'a']++; } for(int i=0;i<27;i++){ if(arr[i]&1){ puts("NO"); return ; } } int pos=1; printf("YES\n"); for(int i=0;i<n;i++){ if(s[i]!=t[i]){ t1[pos].a=t[i]; t1[pos].x1=i; s1[pos].a=s[i]; s1[pos++].x1=i; } } int ans=0; int end1=s1[pos-1].x1; for(int i=1;i<pos;i++){ bool flag=0; for(int j=i+1;j<pos;j++){//从t中寻找与t相等的字符 ,找到后直接交换 if(t1[j].a==t1[i].a) { ans++; flag=1; ar[ans]=s1[i].x1+1; br[ans]=t1[j].x1+1; swap(s1[i].a,t1[j].a); break; } } if(flag) continue ; for(int j=i+1;j<pos;j++){//从s中寻找与s相等的字符 if(s1[j].a==s1[i].a){ flag=1; ans++; ar[ans]=s1[j].x1+1; br[ans]=t1[i].x1+1; swap(s1[j].a,t1[i].a); break; } } if(flag) continue ; for(int j=i+1;j<pos;j++) //从t中寻找与s相等的,然后通过与某个数交换 { if(s1[i].a==t1[j].a){ ans++; ar[ans]=end1+1; br[ans]=t1[j].x1+1; ans++; swap(t1[j].a,s1[pos-1].a); swap(s1[pos-1].a,t1[i].a); ar[ans]=end1+1; br[ans]=t1[i].x1+1; break; } } } printf("%d\n",ans); for(int i=1;i<=ans;i++){ cout<<ar[i]<<" "<<br[i]<<endl; } return ; } int main(){ int t; cin>>t; while(t--) solve(); return 0; }