目标柏林
Time Limit: 1000 ms Case Time Limit: 1000 ms Memory Limit: 64 MB
Description
1945年初,苏军和英美联军已从东西两面攻入德国国境。
4月初,在苏军和英美联军的夹击下,德军只能龟缩在以柏林为中心的德国东部的狭长地带,成了瓮中之鳖。
但希特勒困兽犹斗,一方面发出摧毁一切设施,实行“焦土”政策的指令;
另一方面下令把德国分为南北两个行政区,各自作战,他自己则固守柏林。
在这一天,苏军结果一份传自柏林的加密电文。经初步破译,显示希特勒要调集100万兵力,
在柏林周围筑起了三层防卫圈,并集中3300架飞机,1500多辆坦克,1万门火炮和迫击炮,准备死守柏林。
形势很危机,我们需要马上破译所有密码。请你来遍个程序帮忙破译。
苏军知道德军用的加密方法是这样的:
1.获得一段文字后,求出它的长度(包括空格)len。
2.进入加密运算的第1步:把所有下标是1倍数的字符做顺时针旋转。
3.进入加密运算的第2步:把所有下标是2倍数的字符做逆时针旋转。
4.进入加密运算的第3步:把所有下标是3倍数的字符做顺时针旋转。
5.按上面的规则,第奇数步按顺时针旋转,偶数步按逆时针旋转,一直到第len步为止。
比如原文是:abcde
1.获得长度len = 5
2.1的倍数有1、2、3、4、5,所以把这5个字符按顺时针旋转,得到eabcd。
3.2的倍数有2、4,所以把这2个字符按逆时针旋转,得到ecbad。
4.3的倍数有3,所以把这1个字符按顺时针旋转,得到ecbad。
5.4的倍数有4,所以把这1个字符按逆时针旋转,得到ecbad。
6.5的倍数有5,所以把这1个字符按顺时针旋转,得到ecbad。
最后的结果是ecbad。
现在给你加密后的文章,让你还原成原来的文章。
4月初,在苏军和英美联军的夹击下,德军只能龟缩在以柏林为中心的德国东部的狭长地带,成了瓮中之鳖。
但希特勒困兽犹斗,一方面发出摧毁一切设施,实行“焦土”政策的指令;
另一方面下令把德国分为南北两个行政区,各自作战,他自己则固守柏林。
在这一天,苏军结果一份传自柏林的加密电文。经初步破译,显示希特勒要调集100万兵力,
在柏林周围筑起了三层防卫圈,并集中3300架飞机,1500多辆坦克,1万门火炮和迫击炮,准备死守柏林。
形势很危机,我们需要马上破译所有密码。请你来遍个程序帮忙破译。
苏军知道德军用的加密方法是这样的:
1.获得一段文字后,求出它的长度(包括空格)len。
2.进入加密运算的第1步:把所有下标是1倍数的字符做顺时针旋转。
3.进入加密运算的第2步:把所有下标是2倍数的字符做逆时针旋转。
4.进入加密运算的第3步:把所有下标是3倍数的字符做顺时针旋转。
5.按上面的规则,第奇数步按顺时针旋转,偶数步按逆时针旋转,一直到第len步为止。
比如原文是:abcde
1.获得长度len = 5
2.1的倍数有1、2、3、4、5,所以把这5个字符按顺时针旋转,得到eabcd。
3.2的倍数有2、4,所以把这2个字符按逆时针旋转,得到ecbad。
4.3的倍数有3,所以把这1个字符按顺时针旋转,得到ecbad。
5.4的倍数有4,所以把这1个字符按逆时针旋转,得到ecbad。
6.5的倍数有5,所以把这1个字符按顺时针旋转,得到ecbad。
最后的结果是ecbad。
现在给你加密后的文章,让你还原成原来的文章。
Input
输入一篇加密后的文章,每行为一段。每段不超过1000个字符。
输入以文件结束(EOF)为止。
输入以文件结束(EOF)为止。
Output
输出解密后的文章。
每段一行。
每段一行。
Sample Input
Original | Transformed |
ecbad
Sample Output
Original | Transformed |
abcde
Hint
C and C++ language can use :
char input[1001];
while(gets(input))
{
...
}
char input[1001];
while(gets(input))
{
...
}
Source
Redraiment
———————————————————嘟嘟噜Okari分割线———————————————————
思路:其实这是一个悲伤的故事。刚开始OJ的时候,这道题难住了我。因为我看不懂题意。什么叫顺时针旋转字符?两个字符不论顺时针还是逆时针,都只是交换位置。而一群字符的话……一群怎么旋转?其实,这一题的叙述者根本没说清楚。很简单,顺时针就是说从该字符开始依次替代后一个字符,最后一个字符回到起始字符处。
另外,虽然gets()函数被禁止使用(它实在是太危险!不管数组有多大,不停地向里面塞东西),但是我这么跟你说吧。不用它你肯定WA。唉。
代码如下:
———————————————————嘟嘟噜Okari分割线———————————————————
思路:其实这是一个悲伤的故事。刚开始OJ的时候,这道题难住了我。因为我看不懂题意。什么叫顺时针旋转字符?两个字符不论顺时针还是逆时针,都只是交换位置。而一群字符的话……一群怎么旋转?其实,这一题的叙述者根本没说清楚。很简单,顺时针就是说从该字符开始依次替代后一个字符,最后一个字符回到起始字符处。
另外,虽然gets()函数被禁止使用(它实在是太危险!不管数组有多大,不停地向里面塞东西),但是我这么跟你说吧。不用它你肯定WA。唉。
代码如下:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main(){
char s[1010];
int len;
char c, u;
while(gets(s)){
len = strlen(s);
for(int i = len >> 1; i > 1; i--){//我们稍微一算,就发现只有len/2处之前的数字i的倍数拥有加密机会。而且我们不需要解密第一层操作,1的倍数嘛!
int cou = 1;//1倍2倍3倍4倍5倍……
if(i%2){
//逆时针(由于是解密,因此反了过来)
u = s[i-1];//下标从0开始,所以都减1
while(i*(cou+1) <= len){
s[i*cou-1] = s[i*(cou+1)-1];
cou++;
}
s[i*cou-1] = u;
}
else{
//顺时针
c = s[i-1];
while(i*(cou+1) <= len){
u = s[i*(cou+1)-1];
s[i*(cou+1)-1] = c;
c = u;//替代,这里我想了很久
cou++;
}
s[i-1] = c;
}
}
for(int i = 1; i < len; i++)
printf("%c", s[i]);
printf("%c\n", s[0]);//对第一层解密,我们把首字符输出到最后即可
}
return 0;
}