题目:String change
把26个字母看成0~25对应的数字,当数慢慢增大时就对26取模,则字符串有一个总和s1,要使其变为末状态的总和s2;那么每交换一次s1要加2,故,s1+s2必须为偶数。两个字母单独处理,两个以上时,
以三个数字为例,(a,b,c)为三个数,则有(a,b,c)->(a,c+1,b+1)->(c+2,,a+1,b+1)->(c再分别
和a,b各交换12次,有(c+26,a+13,b+13),再a,b相互交换13次得(c+26,b+26,a+26);
而26为一个周期,即39次交换后由(a,b,c)->(c,b,a)(中间不动,两边交换了);
同理可证39次交换后,可由(a,b,c)->(b,a,c)(一边不动,相邻的交换);
因此,一开始可任意按需要进行交换使s1中的各数与s2中的各数相等,再进行调位置。
如果是两个数就不一样了,设要由(a1,a2)->(b1,b2),则a1必经偶数变为b1或经奇数步
变为b2;又由于26步之后a1,a2又会变回原状态,故必在26步之内要解决变形,先设a1变形成功,再只须检查a2有没有变形成功即可。
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; char a[100],b[100]; int main() { int cas,T=1,a1,a2,b1,b2; scanf("%d",&cas); while(cas--) { int i,t=0; scanf("%s%s",a,b); int len=strlen(a); if(len>2) { for(i=0;i<len;i++) t+=(a[i]-'a'+b[i]-'a'); if(t&1) printf("Case #%d: NO\n",T++); else printf("Case #%d: YES\n",T++); } else { a1=a[0]-'a'; a2=a[1]-'a'; b1=b[0]-'a'; b2=b[1]-'a'; i=(b1-a1+26)%26; if(i%2==0&&(a2+i)%26==b2) printf("Case #%d: YES\n",T++); else { i=(b2-a1+26)%26; if(i%2==1&&(a2+i)%26==b1) printf("Case #%d: YES\n",T++); else printf("Case #%d: NO\n",T++); } } } return 0; }