fork download
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <ctype.h>
  4.  
  5. int main() {
  6. int n;
  7. scanf("%d", &n);
  8. char s[1005][205];
  9. for (int i = 0; i < n; i++) {
  10. scanf("%s", s[i]);
  11. }
  12.  
  13. // 第一階段:找最長公共前綴
  14. char prefix[205];
  15. strcpy(prefix, s[0]);
  16. for (int i = 1; i < n; i++) {
  17. int j = 0;
  18. while (prefix[j] && s[i][j] && prefix[j] == s[i][j])
  19. j++;
  20. prefix[j] = '\0';
  21. if (prefix[0] == '\0')
  22. break;
  23. }
  24. printf("%s\n", prefix);
  25.  
  26. // 第二階段:維吉尼亞解密
  27. char ciphertext[10005];
  28. scanf("%s", ciphertext);
  29.  
  30. int prefix_len = strlen(prefix);
  31. int cipher_len = strlen(ciphertext);
  32.  
  33. if (prefix_len == 0) {
  34. // 如果沒有公共前綴,無法解密
  35. printf("\n");
  36. } else {
  37. char plaintext[10005];
  38. int key_index = 0; // 獨立的 key 索引,只在處理字母時增加
  39.  
  40. for (int i = 0; i < cipher_len; i++) {
  41. char c = ciphertext[i];
  42.  
  43. if (isupper(c)) {
  44. // 大寫字母解密
  45. char key_char = tolower(prefix[key_index % prefix_len]);
  46. int shift = key_char - 'a';
  47. plaintext[i] = ((c - 'A' - shift + 26) % 26) + 'A';
  48. key_index++; // 只有處理字母時才移動 key
  49. } else if (islower(c)) {
  50. // 小寫字母解密
  51. char key_char = tolower(prefix[key_index % prefix_len]);
  52. int shift = key_char - 'a';
  53. plaintext[i] = ((c - 'a' - shift + 26) % 26) + 'a';
  54. key_index++; // 只有處理字母時才移動 key
  55. } else {
  56. // 非字母字符保持不變,不消耗 key
  57. plaintext[i] = c;
  58. }
  59. }
  60. plaintext[cipher_len] = '\0';
  61. printf("%s\n", plaintext);
  62. }
  63.  
  64. return 0;
  65. }
Success #stdin #stdout 0.01s 5288KB
stdin
2
special
specially
Ztpnw, Wzjah! Jww Ljt Cqc?
stdout
special
Hello,