p1449 字符串还原

描述
一个长度为n的由小写字母组成的字符串s_1~s_2~\cdots~s_n~s
1、将字符串翻转,即对于每一个1 ≤ i ≤ n来说,si与s(n-i+1)对换。
2、将字符串中每个字母变为其之后第k个字母,定义z之后的字母为a,其中0 ≤ k ≤ 6且为未知数
​3、将字符串中每个字母变为其之前第k个字母,定义a之前的字母为z,k同2所述。
例如字符串abcd按上面3种方式加密后,在k=1的情况下会依次变为:

1、dcba;
2、bcde;
3、zabc。
现给出信中按以上3种形式分别加密后的3个字符串(不一定按上述例子的顺序),要求还原原来的字符串,并输出告诉小K。

格式
输入格式
输入的第1行为一个整数n,表示这个字符串的长度。

下面3行每行1个长度为n的字符串,且保证符合题目要求。

输出格式
输出仅包括1行,为还原后的字符串。

样例1
样例输入1
4
zabc
dcba
bcde
样例输出1
abcd

思路
题干中指出只有三种变换方式,不管怎么变换,三种密文的头字母或者尾字母是相互之间存在联系的。我们以头字母为例,假设明文的头字母为a,移动数k为1,则以3)为条件变换的密文的头字母则为'a+26-1',以2)为条件变换的密文的头字母则为'a+1',以1)为条件变换的密文的尾字母即为头字母,故将3)与2)的头字母相加减去1)的尾字母得到的数为26。当头字母处于字母表末位的时候数字会超出26,此时我们使用模运算为0即可,类似循环队列的做法。

代码

#include <stdio.h>
#include <stdlib.h>
#define MAX 10000+10
void reverse(char str[],int n);
int main(){
    char a[MAX], b[MAX], c[MAX];
    int n;
    scanf("%d",&n);
    scanf("%s %s %s",a,b,c);
    if((a[0]+b[0]-c[n-1]-c[n-1])==26){
        reverse(c,n);
    }
    else if((a[0]+c[0]-b[n-1]-b[n-1])==26){
        reverse(b,n);
    }
    else{
        reverse(a,n);
    }
    return 0;
}
void reverse(char str[],int n){
    char res[MAX];
    int i;
    for(i=n-1;i>=0;i--){
        res[n-1-i]=str[i];
    }
    res[n]='\0';
    printf("%s",res);
}

 troubleshooting

由于没有反序转换字符串的函数,所以这里我们要自己动手,特别注意的是字符串结尾存储的是'\0',这里需要手动加上(来自yachen大神的提醒)。

posted on 2018-02-27 22:05  archemiya  阅读(225)  评论(0编辑  收藏  举报

导航