限制
每个测试点1s忽略密钥的大小写,于是if ord(miyue) > 96 then miyue := chr(ord(miyue)-32)根据公式ord(mingwen) = ord(miwen) - ord(miyue) + 65推算出明文的代码然后检查与密文的大小写是否一致,不一致再+26即可
program viengere;
var k,s,ans:ansistring;
lenk,lens,num,i,sum:longint;
down:array[1..1000] of boolean; //记录是否需要把该字符转回小写
begin
{assign(input,'vigenere.in');
reset(input);
assign(input,'vigenere.out');
rewrite(output);}readln(k); readln(s); lenk:=length(k); lens:=length(s); num:=0; sum:=0;
k:=upcase(k);
for i:=1 to lens do //是否是小写,同时转成大写方便计算,虽然麻烦,但数据只有1000,时间可不计
if ord(s[i])>ord('Z') then
begin
down[i]:=true; s[i]:=chr(ord(s[i])-32);
end;
for i:=1 to lens do //处理
begin
inc(num); if num>lenk then num:=1;
sum:=ord(k[num])-ord('A'); //需要偏移的位数
sum:=ord(s[i])-sum; //偏移后的asc码
if sum<65 then //若小于A要环形结构,+上26
sum:=sum+26;
ans:=ans+chr(sum); //记录,也可以直接判断输出
end;
for i:=1 to lens do //处理答案,输出,可以和上步结合。
begin
if down[i]=true then
write(chr(ord(ans[i])+32))
else
write(ans[i]);
end;
//close(input);
//close(output);
end.
代码二:
program vigenere;
var k,c:ansistring;
l,r,i,d:longint;
f:array[1..1002] of longint;
begin
//assign(input,'vigenere.in');reset(input);
//assign(output,'vigenere.out');rewrite(output);
readln(k); readln(c);
fillchar(f,sizeof(f),0);
l:=length(k); r:=length(c);
for i:=1 to r do
if ord(c[i])>96 then f[i]:=32; //将所有小写字母在f数组的相应位置加上32(大写字母与小写字母在ASC||码表中的差)
k:=upcase(k); c:=upcase(c); //upcase,将字符串里的字符全部改为大写
for i:=1 to r do //一个一个字母循环
begin
d:=(i-1) mod l+1; //密匙重复使用,是该数-1后modl 再加1;也可改为下列两句
//inc(d);
//if d=l+1 then d:=1;
if c[i]<k[d] then write(chr(ord(c[i])-ord(k[d])+91+f[i])) //密匙字母>密文字母,减完的结果是负的,+91,密文表从右往左看,再加上是否为小写的数字
elsewrite(chr(ord(c[i])-ord(k[d])+65+f[i])); //密匙字母<密文字母,减完的结果是正的 ,+65,密文表从左往右看,再加上是否为小写的数字
end;
//close(input);close(output);
end.