HDU4357(数学思维题)

题目: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;
}


 

 

你可能感兴趣的:(HDU4357(数学思维题))