# 46 条题解

• @ 2018-04-23 23:25:23

挺感慨的，一年前读题就读傻了，现在一眼秒了……
基本思路就是先对密钥进行修改，全部变为大写字母，然后根据公式把密文转化为明文。
公式就是c-=(k-'A')（应该还是比较好想的）然后根据原来密文中的大小写形式转化大小写即可。

``````#include<iostream>
#include<cstring>
using namespace std;
int now;
char k[105],c[1005];
int main()
{
cin>>k;
for(int i=0;i<=strlen(k)-1;++i)
if(k[i]>='a')
k[i]-=('a'-'A');
cin>>c;
for(int i=0;i<=strlen(c)-1;++i)
{
if(c[i]>='a')
{
c[i]-=(k[now]-'A');
now++;
while(c[i]<'a')
c[i]+=26;
}
else
{
c[i]-=(k[now]-'A');
now++;
while(c[i]<'A')
c[i]+=26;
}
if(now>strlen(k)-1)
now=0;
}
cout<<c;
return 0;
}
``````
• @ 2017-09-05 21:54:15
``````#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;

char key[128];
char info[1024];
char ans[1024];
#define IsUpperCase(ch) ((ch) >= 'A' && (ch) <= 'Z')
#define UpperCase(ch) (IsUpperCase(ch) ? ch : (ch - 'a' + 'A'))

int main() {
scanf("%s %s", key, info);
for (int i = 0; i < strlen(info); ++ i)
ans[i] = ((UpperCase(info[i]) - UpperCase(key[i % strlen(key)])) + 26) % 26 + (IsUpperCase(info[i]) ? 'A' : 'a');
puts(ans);
return 0;
}
``````
• @ 2016-12-11 04:15:25

唉，今非昔比了，当年用了一个小时还只过了7个点，现在分分钟就写好了，只用了20行一次就AC。
```C++
// P1778vigenere密码 https://vijos.org/p/1778
// by Equim 3:50~4:12
#include <cstdio>
#include <cstring>

int main()
{
// INPUT
char key[101];
char ciphertext[1001];
char plaintext[1001];
scanf("%s", key);
scanf("%s", ciphertext);

// PROCESS
strlwr(key);
int keyLength = strlen(key);
int i;
for(i = 0;ciphertext[i]!='\0';i++)
{
plaintext[i] = ciphertext[i] - (key[i%keyLength]-'a');
if ((ciphertext[i] <= 'Z' && plaintext[i] < 'A') || (ciphertext[i] >= 'a' && plaintext[i] < 'a'))
plaintext[i] += 26;
}
plaintext[i] = '\0';

// OUTPUT
printf("%s", plaintext);
return 0;
}
```

• @ 2017-07-21 09:48:14

要是我也能这样就好了

• @ 2016-11-18 18:23:08
``````program vigenere;

var
k: string;
m, c, kc, ans: char;
i, j, n, l: integer;
low: boolean;

begin
//    assign(input,'vigenere.in'); assign(output,'vigenere.out');
//    reset(input); rewrite(output);
n := 0;
while not eoln{(input)} do
begin
inc(n);
low := true; if (ord(c) <= 90) then low := false; c := upcase(c);
i := n mod l; if (i = 0) then i := l; kc := upcase(k[i]);
j := ord(c) - ord(kc) + 1; if (j <= 0) then j := j + 26; j := j + 64;
ans := chr(j); if low then ans := lowercase(ans);
write(ans);
end;
//    close(input); close(output);
end.
``````
• @ 2016-07-11 19:02:38

进行那个公式前 都要转为大写 ,所有的都是大写 最后 并保持字母在明文M中的大小写形式. 枚举一下就ok

• @ 2021-09-04 14:08:08
``````#include <bits/stdc++.h>
using namespace std;

int main()
{
string k,c; cin>>k>>c;
for (int i=0;i<c.length();i++) {
int t=(k[i%k.length()]&31)-1;
c[i]=(c[i]&31)-t>0?c[i]-t:c[i]-t+26;
}
cout<<c<<endl;
return 0;
}
``````
• @ 2018-02-06 10:11:15
``````#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int k;
int a[110];
char s1[1010], s2[1010];
int change(char c) {
if(c>='A'&&c<='Z') return c-65;
if(c>='a'&&c<='z') return c-97;
return 0;
}
int main() {
char x;
x=getchar();
int j=0;
while((x>='a'&&x<='z')||(x>='A'&&x<='Z')) {
j++;
a[j]=change(x);
x=getchar();
}
scanf("%s", s1);
strcpy(s2, s1);
for(int i=0; i<strlen(s1); i++) {
k=i+1;
k=(k-1)%j+1;
for(int jj=1; jj<=a[k]; jj++) {
s2[i]--;
if(s2[i]==64) s2[i]+=26;
if(s2[i]==96) s2[i]+=26;
}
}
printf("%s", s2);
return 0;
}
``````
• @ 2017-10-02 14:32:05
``````#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#include <vector>
#include <deque>
#include <set>
#include <limits>
#include <string>
#include <sstream>
using namespace std;

const int oo_min=0xcfcfcfcf,oo_max=0x3f3f3f3f;
const int a_n=26;

int c_size,key_size;
int c_v[1000+1];
int m_v[1000+1];
int key_v[1000+1];
#define key_v(x) key_v[(x-1)%key_size+1]
char c[1000+1];
#define c(x) c[x-1]
char key[1000+1];
#define key(x) key[x-1]

int c_t_i_1(char c)
{
if ('A'<=c&&c<='Z')
return c-'A';
else if ('a'<=c&&c<='z')
return c-'a';
}

int main()
{
while (~scanf("%s",key))
{
key_size=strlen(key);
for (int i=1;i<=key_size;i++)
key_v[i]=c_t_i_1(key(i));
getchar();
scanf("%s",c);
c_size=strlen(c);
for (int i=1;i<=c_size;i++)
c_v[i]=c_t_i_1(c(i));
getchar();
for (int i=1;i<=c_size;i++)
{
m_v[i]=(c_v[i]-key_v(i))%a_n;
while (m_v[i]<0)
m_v[i]+=a_n;
if ('A'<=c(i)&&c(i)<='Z')
printf("%c",m_v[i]+'A');
else if ('a'<=c(i)&&c(i)<='z')
printf("%c",m_v[i]+'a');
}
}
}
``````
• @ 2017-10-02 14:32:33

很H2O的题

• @ 2016-11-17 15:44:10

#include <cstdio>
#include <cstring>

int main(){
//freopen("in.txt","r",stdin);
char key[150],A[1500],B[1500],capital[1500]={0};
scanf("%s%s",key,A);
for(int i=0;i<strlen(key);i++)
if('A'<=key[i]&&key[i]<='Z')
key[i]+=-'A'+'a';
for(int i=0;i<strlen(A);i++)
if('A'<=A[i]&&A[i]<='Z'){
capital[i]=1;
A[i]+=-'A'+'a';
}
for(int i=0;i<strlen(A);i++){
for(char c='a';c<='z';c++)
if((c-'a'+key[i%strlen(key)]-'a')%26==A[i]-'a'){
B[i]=c;
break;
}
}
for(int i=0;i<strlen(A);i++)
if(capital[i])
printf("%c",B[i]-'a'+'A');
else
printf("%c",B[i]);
return 0;
}

• @ 2016-11-15 21:51:27
``````#include <iostream>
#include <string>
#include <map>
using namespace std;

string str, strC;
map<char, char> Map[100], _Map[200];

void Init() {
//大写
int nCount = 0;
char C = 0;
for (char ch = 'A'; ch <= 'Z'; ch++) {
nCount = 0;
C = ch;
while (nCount < 26) {
if (C > 'Z') C = 'A';
Map[ch][nCount + 65] = C;

C ++;
nCount ++;
}
}
//小写
for (char ch = 'a'; ch <= 'z'; ch++) {
nCount = 0;
C = ch;
while (nCount < 26) {
if (C > 'z') C = 'a';
_Map[ch][nCount + 97] = C;

C ++;
nCount ++;
}
}
}
int main() {
Init();
//密匙 密文
cin >> str >> strC;
for (int i = 0; i < strC.length(); i++) {
char ch_C = strC[i];
char ch_S = str[i % str.length()];
//大写
if (ch_C >= 'A' && ch_C <= 'Z') {
if (ch_S < 'A' || ch_S > 'Z') ch_S -= 32;
for (char ch = 'A'; ch <= 'Z'; ch++) {
if (Map[ch][ch_S] == ch_C) {
cout << ch;
break;
}
}
}
//小写
else {
if (ch_S < 'a' || ch_S > 'z') ch_S += 32;
for (char ch = 'a'; ch <= 'z'; ch++) {
if (_Map[ch][ch_S] == ch_C) {
cout << ch;
break;
}
}
}
}

return 0;
}
``````
• @ 2016-10-14 13:27:33

要注意大小写！！！！！
``` #include<iostream> #include<cstdio> #include<cstring> using namespace std; char k[105],m[1005],c[1005]; int main(){ int i,j,l,loth; cin>>k; cin>>c; l=strlen(k); loth=strlen(c); for(i=0;i<loth;i++){ int a=i%l,tmp,temp; if(k[a]>='a'&&k[a]<='z') tmp='a'; else if(k[a]>='A'&&k[a]<='Z') tmp='A'; if(c[i]>='a'&&c[i]<='z') temp='a'; else if(c[i]>='A'&&c[i]<='Z') temp='A'; m[i]=(c[i]-temp-k[a]+tmp+52)%26+temp; } cout<<m; return 0; } ```

• @ 2022-08-30 10:01:05
``````#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
void turn(char &x);
int main()
{
char key[1000],secret[1000];
int len1,len2;
int i,j;

cin.getline(key,999,'\n');//输入密钥
cin.getline(secret,999,'\n');//输入密文
len1=strlen(key);//求密钥长度
len2=strlen(secret);//求密文长度

for(i=0; i<len1; i++) //将密钥转换为大写字母
turn(key[i]);

for(i=0,j=0; i<len2; i++) //从头开始解密
{
if(secret[i]<='Z')//大写的情况
{
secret[i]=secret[i]-(key[j]-'A');//按规则解密
j++;
if(secret[i]<'A')//若明文小于A
secret[i]='Z'-('A'-secret[i])+1;//从字母表倒序转换
}
else//小写的情况
{
secret[i]=secret[i]-(key[j]-'A');//按规则解密
j++;
if(secret[i]<'a')//若明文小于a
secret[i]='z'-('a'-secret[i])+1;//从字母表倒序转换
}
if(j>len1-1)//若明文长度大于密钥长度，重复使用密钥
j=0;
}
cout<<secret<<endl;
return 0;
}
void turn(char &x)
{
if((x>='a')&&(x<='z'))
x-=32;
}
``````

超简单，信息奥赛一本通上有

• @ 2020-04-06 15:12:05
``````#include <iostream>         //[2012提高组Day1-A]Vigenère密码
#include <algorithm>
#include <string>
using namespace std;

string Alp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string alp = "abcdefghijklmnopqrstuvwxyz";
int dik(char k)
{
if(k >= 'A' && k <= 'Z')
return k - 'A';
return k - 'a';
}

char Pass(char c, char k)
{
if(c >= 'A' && c <= 'Z')
return Alp[(dik(c) - dik(k) + 26) % 26];
return alp[(dik(c) - dik(k) + 26) % 26];
}

int main()
{
string key, C, M;
cin >> key >> C;
int Lc = C.length(), Lk = key.length();
int j = 0;
for (int i = 0; i < Lc; i++)
{
M += Pass(C[i], key[j]);
j = (j + 1) % Lk;
}
cout << M << endl;
system("pause");
return 0;
}

``````
• @ 2018-02-06 10:08:03
``````#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int k;
int a[110];
char s1[1010], s2[1010];
int change(char c) {
if(c>='A'&&c<='Z') return c-65;
if(c>='a'&&c<='z') return c-97;
return 0;
}
int main() {
char x;
x=getchar();
int j=0;
while((x>='a'&&x<='z')||(x>='A'&&x<='Z')) {
j++;
a[j]=change(x);
x=getchar();
}
scanf("%s", s1);
strcpy(s2, s1);
for(int i=0; i<strlen(s1); i++) {
k=i+1;
k=(k-1)%j+1;
for(int jj=1; jj<=a[k]; jj++) {
s2[i]--;
if(s2[i]==64) s2[i]+=26;
if(s2[i]==96) s2[i]+=26;
}
}
printf("%s", s2);
return 0;
}
``````
• @ 2016-11-15 21:51:06

感觉原题意更好写啊 有一个表的 MAP一下就好了啊

#include <iostream>
#include <string>
#include <map>
using namespace std;

string str, strC;
map<char, char> Map[100], _Map[200];

void Init() {
//大写
int nCount = 0;
char C = 0;
for (char ch = 'A'; ch <= 'Z'; ch++) {
nCount = 0;
C = ch;
while (nCount < 26) {
if (C > 'Z') C = 'A';
Map[ch][nCount + 65] = C;

C ++;
nCount ++;
}
}
//小写
for (char ch = 'a'; ch <= 'z'; ch++) {
nCount = 0;
C = ch;
while (nCount < 26) {
if (C > 'z') C = 'a';
_Map[ch][nCount + 97] = C;

C ++;
nCount ++;
}
}
}
int main() {
Init();
//密匙 密文
cin >> str >> strC;
for (int i = 0; i < strC.length(); i++) {
char ch_C = strC[i];
char ch_S = str[i % str.length()];
//大写
if (ch_C >= 'A' && ch_C <= 'Z') {
if (ch_S < 'A' || ch_S > 'Z') ch_S -= 32;
for (char ch = 'A'; ch <= 'Z'; ch++) {
if (Map[ch][ch_S] == ch_C) {
cout << ch;
break;
}
}
}
//小写
else {
if (ch_S < 'a' || ch_S > 'z') ch_S += 32;
for (char ch = 'a'; ch <= 'z'; ch++) {
if (_Map[ch][ch_S] == ch_C) {
cout << ch;
break;
}
}
}
}

return 0;
}

• @ 2016-11-15 09:26:46
``````#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
//Limits
const int N=100;
const int M=1000;
const int MOD=26;
//Main
char key[N+1];
char cip[M+1];
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%s",key+1);
int keylen=strlen(key+1);
scanf("%s",cip+1);
int ciplen=strlen(cip+1);
int i=1;
for(int j=1;j<=ciplen;j++)
{
int k=tolower(key[i])-'a';
int c=tolower(cip[j])-'a';
int m=(c-k+MOD)%MOD+'a';
if(isupper(cip[j]))m=toupper(m);
printf("%c",m);
i++;
if(i==keylen+1)i=1;
}
printf("\n");
return 0;
}
``````
• @ 2016-11-12 14:23:13
``````#include <iostream>
#include <cstring>
using namespace std;
char k[101],a[1001],b[1001],c[1001];
int main()
{
int size,i,keys;
gets(k);
gets(a);
size=strlen(a);
keys=strlen(k);
for(int i=0;i<size;i++)
{
if(k[i]>='a'&&k[i]<='z')    k[i]-=32;
if(a[i]>='a'&&a[i]<='z')    b[i]=a[i]-32;
else b[i]=a[i];
}
for(i=0;i<size;i++)
{
int j=i%keys;
if(b[i]>=k[j])
c[i]=b[i]+65-k[j];
else
c[i]=b[i]+65-k[j]+26;
if(a[i]>='a'&&a[i]<='z')    c[i]+=32;

}
cout<<c;
return 0;
}
``````
• @ 2016-08-29 16:49:54

先让密钥足够长，然后枚举每一位可能的字母，判断，最后输出即可。
用ansistring
```pascal var k,m,s:ansistring; i:longint; c:char; begin readln(k); readln(m); s:=m; k:=upcase(k); m:=upcase(m); while length(k)<length(m)do k:=k+k; for i:=1 to length(m)do for c:='A'to'Z'do if ord(m[i])=(ord(c)-ord('A')*2+ord(k[i]))mod 26+ord('A')then begin m[i]:=c; break; end; for i:=1 to length(m)do if s[i]=upcase(s[i])then write(m[i])else write(lowercase(m[i])); writeln; end. ```

• @ 2016-05-15 11:07:46

网上搜了搜原题是有表的
公式要自己思考出来

``````#include <cstdio>
#include <cstring>
#include <iostream>

int main(){
char key[150];
char classified[1500];
std::cin>>key>>classified;
int i=0,len=strlen(key);
int capital,c;
while(classified[i]!='\0'){
c=key[i%len];
capital=c>='A'&&c<='Z';
if(!capital)
key[i%len]+=-'a'+'A';

c=classified[i];
capital=c>='A'&&c<='Z';
if(!capital)
c=c-'a'+'A';
for(int x='A';x<='Z';x++)
if(c==(x-'A'+key[i%len]-'A')%26+'A')
if(capital)
printf("%c",x);
else
printf("%c",x-'A'+'a');
i++;
}
return 0;
}
``````
• @ 2016-07-11 19:03:06

不要贴代码,这样子不好

• @ 2016-10-14 13:27:26

贴代码只是提供给别人一个参考

• @ 2015-11-15 18:39:45

评测状态 Accepted
题目 P1778 vigenere密码
递交时间 2015-11-15 18:32:15
代码语言 C++
评测机 VijosEx
消耗时间 45 ms
消耗内存 252 KiB
评测时间 2015-11-15 18:32:17

评测结果

编译成功

foo.cpp: In function 'char qw(char, char)':
foo.cpp:31:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^

测试数据 #0: Accepted, time = 15 ms, mem = 248 KiB, score = 10

测试数据 #1: Accepted, time = 0 ms, mem = 252 KiB, score = 10

测试数据 #2: Accepted, time = 0 ms, mem = 248 KiB, score = 10

测试数据 #3: Accepted, time = 0 ms, mem = 252 KiB, score = 10

测试数据 #4: Accepted, time = 15 ms, mem = 248 KiB, score = 10

测试数据 #5: Accepted, time = 0 ms, mem = 252 KiB, score = 10

测试数据 #6: Accepted, time = 0 ms, mem = 248 KiB, score = 10

测试数据 #7: Accepted, time = 15 ms, mem = 252 KiB, score = 10

测试数据 #8: Accepted, time = 0 ms, mem = 252 KiB, score = 10

测试数据 #9: Accepted, time = 0 ms, mem = 252 KiB, score = 10

Accepted, time = 45 ms, mem = 252 KiB, score = 100

ID
1778

3

3055

1491

49%

9