ZJU OJ 1009 Enigma
比较晕的模拟题目,倒过来算circuit偏差值就可以,逻辑很简单,但有点绕
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 1000 #define ROTOR_COUNT 3 #define INDEX(i) ((i + size)%size) #define reset_rotors rotors[0].revolve_times = rotors[1].revolve_times = rotors[2].revolve_times = 0; typedef struct _rotor { int circuit[27]; int revolve_times; } Rotor; Rotor rotors[3]; static int size; void setup_rotors(); void decrypt(char* word); char decrypt_one_char(char c); void revolve_rotors(); int main(int argc, char** argv) { int case_number = 1; char words[MAX]; scanf("%d", &size); while(size) { int case_size, i; printf("Enigma %d:\n", case_number); setup_rotors(); scanf("%d", &case_size); for(i = 0; i < case_size; i ++) { scanf("%s", words); decrypt(words); reset_rotors; } scanf("%d", &size); case_number ++; if(size) putchar('\n'); } return 0; } void setup_rotors() { int i, index; reset_rotors; for(i = 0; i < ROTOR_COUNT; i ++) { char table[27]; scanf("%s", table); for(index = 0; index < size; index ++) { rotors[i].circuit[table[index] - 'A'] = 'A' + index - table[index]; } } } void decrypt(char* word) { char orig_words[MAX], c; int i, word_length = strlen(word); for(i = 0; i < word_length; i ++) { orig_words[i] = decrypt_one_char(word[i]); } orig_words[i] = '\0'; printf("%s\n", orig_words); } char decrypt_one_char(char c) { int i; for(i = ROTOR_COUNT - 1; i >= 0; i --) { c = (rotors[i].circuit[INDEX(c - 'A' - rotors[i].revolve_times)] + c - 'A' + size)%size + 'A'; } revolve_rotors(); return c - 'A' + 'a'; } void revolve_rotors() { int i = 0; for(rotors[0].revolve_times += 1; i < ROTOR_COUNT, rotors[i].revolve_times == size; i ++) { rotors[i].revolve_times = 0; rotors[i + 1].revolve_times += 1; } }