解题笔记 之 1009 恶心的模拟

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;
    }
}


 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值