题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1009

题目大意:给你三个转换轮,只有当第一个转换轮转动一圈后第二个才会转,当第二个转动一圈后第三个才会转。转换轮的意思是我按动一个按钮,显示器经过转换轮的转换显示另外一个字母。每按下一个按钮,第一个转换轮都会转动一次。

叉姐说得好,多学习一下思维方法,有些问题都是能够很高效率的想出来的。脑洞什么的全是骗人的。

注意看这张图:

中间转动轮的点, 左右两边是一一对应的。

也就是说,无论转动轮怎么转,都能把左边的keyboard和右边的display一一对应上,不重不漏。

那么,我们给rotor左边的接口依次标号1,2,3,4,5,6 并且根据第一个状态读出对应关系。即1,-1,1,2,0,-3

经过对应关系,我们把keyboard上的标为A集合{a,b,c,d,e,f} 经过对应关系B {1,-1,1,2,0,-3}, 得到 {a+1,b-1,c+1,d+2,e+0,f-3} => {b,a,d,f,e,c}

然后再经过一层对应关系C {0,0,1,1,1,-3} => {b,a,e,f,c,d} ,注意第二个关系是把a+0,b+0,c+1,d+1,f+1,e-3,也就是说不管上一个映射怎么变,这一个还是对abcdef进行映射。

那么,这就可以列出来转移映射关系式了: cc[i] = tmp[i]+r[tmp[i]];

再加上偏移:cc[i] = tmp[i]+r[((tmp[i]-st)%m+m)%m]

再对整个做负数处理:cc[i] = ((tmp[i]+r[((tmp[i]-st)%m+m)%m])%m+m)%m

我就是这里没想好,卡了好久。

到这里,题目就做了一大半。

接下来,我们发现A经过三次映射到了D

那么也就是说我们可以把中间的关系合并起来  A -> D。

表示成f(A) = D

那么求反函数即可g(D) = A

接下来就是链表的事情咯。

 #include <cstdio>
#include <cstdlib>
#include <string>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <vector>
#include <map>
#include <set>
#include <iterator>
#include <functional>
#include <cmath>
#include <numeric>
#include <ctime>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef vector<int> VI;
#define PB push_back
#define MP make_pair
#define SZ size()
#define CL clear()
#define AA first
#define BB second
#define EPS 1e-8
#define ZERO(x) memset((x),0,sizeof(x))
const int INF = ~0U>>;
const double PI = acos(-1.0); int m,n;
char r[][];
int e[][];
const int MAX_N = **;
int tmp[]; struct CircularNode{
int lst[];
int num;
CircularNode *next;
CircularNode(int n){
memset(lst,,sizeof(lst));
num = n;
next = NULL;
}
~CircularNode(){
if( next ){
delete next;
next = NULL;
}
}
}; struct CircularList{
CircularNode *rt,*cur;
~CircularList(){
delete rt;
}
CircularList(){
rt = NULL;
}
void push_back(int a[],int m){
if( !rt ) {
rt = new CircularNode(m);
cur = rt;
} else {
cur->next = new CircularNode(m);
cur = cur->next;
} for(int j=;j<m;j++){
cur->lst[a[j]] = j;
}
}
}; void mapping(int *r,int st){
int cc[];
for(int i=;i<m;i++){
cc[i] = ((tmp[i]+r[(tmp[i]-st+m)%m])%m+m)%m;
}
for(int i=;i<m;i++){
tmp[i] = cc[i];
}
} int main(){
int kase = ;
while(scanf("%d",&m),m){
if(kase!=) puts("");
printf("Enigma %d:\n",kase++);
for(int i=;i<;i++) scanf("%s",r[i]);
for(int i=;i<;i++){
for(int j=;j<m;j++){
e[i][j] = r[i][j] - 'A' - j;
// printf("%d ",e[i][j]);
}
// puts("");
} CircularList *aCircularList = new CircularList; for(int st1=;st1<m;st1++){
for(int st2=;st2<m;st2++){
for(int st3=;st3<m;st3++){
for(int i=;i<m;i++) tmp[i] = i;
mapping(e[],st3);
// for(int i=0;i<m;i++) printf("%d ",tmp[i]); puts("");
mapping(e[],st2);
// for(int i=0;i<m;i++) printf("%d ",tmp[i]); puts("");
mapping(e[],st1);
// for(int i=0;i<m;i++) printf("%d ",tmp[i]); puts("");
aCircularList->push_back(tmp,m);
// for(int i=0;i<m;i++){
// printf("%d ",aCircularList->cur->lst[i]);
// }
// puts("");
}
// exit(0);
}
} scanf("%d",&n);
getchar();
int kase = ;
while(n--){
CircularNode *p = aCircularList->rt;
char c;
while( (c=getchar())!='\n' ){
// printf("%d\n",p->lst[c-'A']);
putchar('a'+p->lst[c-'A']);
p = p->next;
if(!p) p = aCircularList->rt;
}
puts("");
} delete aCircularList;
}
return ;
} /*
6
FDBCAE
ABDEFC
CDAFEB
1
ACE
*/

[ZOJ 1009] Enigma (模拟)的更多相关文章

  1. 1009 Enigma

    本题的重点是理解清楚题意并能代码模拟.形式是二战德国密码机,和数据结构.算法联系较少. #include <stdio.h> #include <string.h> int m ...

  2. Enigma模拟-Python

    设计思想 Enigma机的机械结构: 键盘:加密人员通过键盘进行输入 转子:Enigma机上一般装有至少3个转轮.每个转轮有代表26个字母的触头和触点,触点和触头在转轮内部有导线相连(一个转轮相当于一 ...

  3. A - Jugs ZOJ - 1005 (模拟)

    题目链接:https://cn.vjudge.net/contest/281037#problem/A 题目大意:给你a,b,n.a代表第一个杯子的容量,b代表第二个杯子的容量,然后一共有6种操作.让 ...

  4. ZOJ 2610 Puzzle 模拟

    大模拟:枚举6个方向.检查每一个0是否能移动 Puzzle Time Limit: 2 Seconds      Memory Limit: 65536 KB Little Georgie likes ...

  5. Capture the Flag ZOJ - 3879(模拟题)

    In computer security, Capture the Flag (CTF) is a computer security competition. CTF contests are us ...

  6. ZOJ 3705 Applications 模拟

    #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include< ...

  7. ZOJ 3652 Maze 模拟,bfs,读题 难度:2

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4842 要注意题目中两点: 1.在踏入妖怪控制的区域那一刹那,先减行动力,然后才 ...

  8. ZOJ 1122 Clock(模拟)

    Clock Time Limit: 2 Seconds      Memory Limit: 65536 KB You are given a standard 12-hour clock with ...

  9. POJ题目细究

    acm之pku题目分类 对ACM有兴趣的同学们可以看看 DP:  1011   NTA                 简单题  1013   Great Equipment     简单题  102 ...

随机推荐

  1. 通过新浪ip地址库获得用户的省份、城市等信息

    <script src="http://apps.bdimg.com/libs/jquery/1.11.3/jquery.min.js"></script> ...

  2. openssl数字证书私钥删除私钥密码

    解密 openssl rsa -in server.key.org -out server.key

  3. C#子线程刷新界面并关闭窗体

    目的:要循环刷新界面上的控件,同时不影响用户操作.循环结束后关闭窗体. 步骤:先创建一个窗体,窗体中拖入一个lable控件(label1),一个button控件(button1) 代码窗口输入: // ...

  4. MVC4 WebAPI(一)

    http://www.cnblogs.com/wk1234/archive/2012/04/28/2468491.html 不管是因为什么原因,结果是在新出的MVC中,增加了WebAPI,用于提供RE ...

  5. IOS开发-PCH文件的使用

    PCH文件存储一些共享的数据,在其他的文件可以直接使用,这样减少程序输入,比如存储宏定义 1.首先新建PCH文件 2.建立完毕 3.在这里找到文件路径 4.进入targets 点击Build Sttt ...

  6. fiddler Android下https抓包全攻略

    fiddler Android下https抓包全攻略 fiddler的http.https的抓包功能非常强大,可非常便捷得对包进行断点跟踪和回放,但是普通的配置对于像招商银行.支付宝.陌陌这样的APP ...

  7. erlang和go之间桥接库相关

    https://github.com/goerlang

  8. c/c++多线程编程中最好不要加volatile

    来自https://www.zhihu.com/question/31459750 答主解释说:不能指望volatile能解决多线程竞争问题,除非所用的环境系统不可靠才会为了保险加上volatile, ...

  9. Sublime text2用户自定义配置

    [{ "keys": ["ctrl+d"], "command": "run_macro_file", "ar ...

  10. 二. Socket用法

    C/S通信架构中,客户端要主动与服务端建立连接,这个链接就是Socket套接字.服务端收到连接请求后,也会开启Socket记录与客户端的链接.C/S两端都要建路Socket才能正常收发数据. 一.构造 ...