一、描述
一个长度为n的由小写字母组成的字符串s_1~s_2~\cdots~s_n~s1 s2 ⋯ sn 按如下方式加密成3种形式:
- 将字符串翻转,即对于每一个1\le i\le n~1≤i≤n 来说,s_i~si 与s_{n-i+1}~sn−i+1 对换。
- 将字符串中每个字母变为其之后第k个字母,定义z之后的字母为a,其中0≤k≤6且为未知数。
- 将字符串中每个字母变为其之前第k个字母,定义a之前的字母为z,k同2所述。
例如字符串abcd按上面3种方式加密后,在k=1k=1的情况下会依次变为:
- dcba
- bcde
- zabc
现给出信中按以上3种形式分别加密后的3个字符串(不一定按上述例子的顺序),要求还原原来的字符串。
二、格式
- 输入格式 输入的第1行为一个整数n,表示这个字符串的长度。下面3行每行1个长度为n的字符串,且保证符合题目要求。
- 输出格式 输出仅包括1行,为还原后的字符串。
三、思路
将其中一个字符串看成是经过翻转后的,则该字符串的首字母分别与其他两个字符串的首字母的差(对应的ASCII码值)的绝对值 X ,Y应该相等,并且等于k,所以只要判断X和Y是否相等即可。考虑到字母a向前一个字母是z,X 或 Y 的值有可能大于6(k的取值范围是0-6),注意到26个字母形成了一个类似循环队列的结构,所以任意两个字母之间的差的绝对值都应该小于26/2=13,所以最终得到X或Y的值应该是 X= (X>13)?(26-X):X 、Y=(Y>13)?(26-Y):Y。
四、代码
import java.util.Scanner;public class Main { public static int n=0; public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc = new Scanner(System.in); n = sc.nextInt(); String str1 = sc.next(); String str2 = sc.next(); String str3 = sc.next(); if(getStr(str1,str2,str3)){ System.out.println(strReverse(str1)); } if(getStr(str2,str1,str3)){ System.out.println(strReverse(str2)); } if(getStr(str3,str1,str2)){ System.out.println(strReverse(str3)); } } public static String strReverse(String str){ String result =""; for(int i =str.length()-1;i>=0;i--){ result += str.charAt(i); } return result; } public static boolean getStr(String str1,String str2,String str3){ boolean flag = true; String str = strReverse(str1); for(int i = 0;i13?(26-m):m; int n = Math.abs((str3.charAt(0)-str.charAt(0))); n = n>13?(26-n):n; if(m!=n){ flag=false; break; } } return flag; }}