[ZOJ 1009] Enigma (模拟)

题目链接: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

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

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <string>
  4 #include <iostream>
  5 #include <cstring>
  6 #include <algorithm>
  7 #include <cctype>
  8 #include <vector>
  9 #include <map>
 10 #include <set>
 11 #include <iterator>
 12 #include <functional>
 13 #include <cmath>
 14 #include <numeric>
 15 #include <ctime>
 16 using namespace std;
 17 typedef long long LL;
 18 typedef pair<int,int> PII;
 19 typedef vector<int> VI;
 20 #define PB push_back
 21 #define MP make_pair
 22 #define SZ size()
 23 #define CL clear()
 24 #define AA first
 25 #define BB second
 26 #define EPS 1e-8
 27 #define ZERO(x) memset((x),0,sizeof(x))
 28 const int INF = ~0U>>1;
 29 const double PI = acos(-1.0);
 30
 31 int m,n;
 32 char r[3][30];
 33 int e[3][30];
 34 const int MAX_N = 30*30*30;
 35 int tmp[30];
 36
 37 struct CircularNode{
 38     int lst[30];
 39     int num;
 40     CircularNode *next;
 41     CircularNode(int n){
 42         memset(lst,0,sizeof(lst));
 43         num = n;
 44         next = NULL;
 45     }
 46     ~CircularNode(){
 47         if( next ){
 48             delete next;
 49             next = NULL;
 50         }
 51     }
 52 };
 53
 54 struct CircularList{
 55     CircularNode *rt,*cur;
 56     ~CircularList(){
 57         delete rt;
 58     }
 59     CircularList(){
 60         rt = NULL;
 61     }
 62     void push_back(int a[],int m){
 63         if( !rt ) {
 64             rt = new CircularNode(m);
 65             cur = rt;
 66         } else {
 67             cur->next = new CircularNode(m);
 68             cur = cur->next;
 69         }
 70
 71         for(int j=0;j<m;j++){
 72             cur->lst[a[j]] = j;
 73         }
 74     }
 75 };
 76
 77 void mapping(int *r,int st){
 78     int cc[30];
 79     for(int i=0;i<m;i++){
 80         cc[i] = ((tmp[i]+r[(tmp[i]-st+m)%m])%m+m)%m;
 81     }
 82     for(int i=0;i<m;i++){
 83         tmp[i] = cc[i];
 84     }
 85 }
 86
 87 int main(){
 88     int kase = 1;
 89     while(scanf("%d",&m),m){
 90         if(kase!=1) puts("");
 91         printf("Enigma %d:\n",kase++);
 92         for(int i=0;i<3;i++) scanf("%s",r[i]);
 93         for(int i=0;i<3;i++){
 94             for(int j=0;j<m;j++){
 95                 e[i][j] = r[i][j] - ‘A‘ - j;
 96 //                printf("%d ",e[i][j]);
 97             }
 98 //            puts("");
 99         }
100
101
102         CircularList *aCircularList = new CircularList;
103
104
105         for(int st1=0;st1<m;st1++){
106             for(int st2=0;st2<m;st2++){
107                 for(int st3=0;st3<m;st3++){
108                     for(int i=0;i<m;i++) tmp[i] = i;
109                     mapping(e[0],st3);
110 //                    for(int i=0;i<m;i++) printf("%d ",tmp[i]); puts("");
111                     mapping(e[1],st2);
112 //                    for(int i=0;i<m;i++) printf("%d ",tmp[i]); puts("");
113                     mapping(e[2],st1);
114 //                    for(int i=0;i<m;i++) printf("%d ",tmp[i]); puts("");
115                     aCircularList->push_back(tmp,m);
116 //                    for(int i=0;i<m;i++){
117 //                        printf("%d ",aCircularList->cur->lst[i]);
118 //                    }
119 //                    puts("");
120                 }
121 //                exit(0);
122             }
123         }
124
125         scanf("%d",&n);
126         getchar();
127         int kase = 1;
128         while(n--){
129             CircularNode *p = aCircularList->rt;
130             char c;
131             while( (c=getchar())!=‘\n‘ ){
132 //                printf("%d\n",p->lst[c-‘A‘]);
133                 putchar(‘a‘+p->lst[c-‘A‘]);
134                 p = p->next;
135                 if(!p) p = aCircularList->rt;
136             }
137             puts("");
138         }
139
140         delete aCircularList;
141     }
142     return 0;
143 }
144
145 /*
146 6
147 FDBCAE
148 ABDEFC
149 CDAFEB
150 1
151 ACE
152 */
时间: 2024-10-09 10:23:31

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

ZOJ 3705 Applications 模拟

#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include<sstream> #include<cmath> #include<climits&g

1009 Enigma

本题的重点是理解清楚题意并能代码模拟.形式是二战德国密码机,和数据结构.算法几乎没有联系. 1 #include <stdio.h> 2 #include <string.h> 3 4 int main(){ 5 char rotor[30],cryp[1000]; 6 int i,j,blank=0,num=1,m,n,temp[26],tran[3][26]; 7 while(scanf("%d", &m)>=0&&m){ 8

ZOJ 2610 Puzzle 模拟

大模拟:枚举6个方向,检查每个0能否移动 Puzzle Time Limit: 2 Seconds      Memory Limit: 65536 KB Little Georgie likes puzzles very much. Recently he has found a wooden triangle in the box with old toys. The side of the triangle is n inches long. The triangle is divided

A - Jugs ZOJ - 1005 (模拟)

题目链接:https://cn.vjudge.net/contest/281037#problem/A 题目大意:给你a,b,n.a代表第一个杯子的容量,b代表第二个杯子的容量,然后一共有6种操作.让你用尽可能少的步骤将第二个杯子的当前的水的体积转换成n. 具体思路:就是队列模拟啊,,,,打比赛的时候脑子瓦特了,没读完题目就开始读了,,,这个毛病确实得改了,, AC代码: 1 #include<iostream> 2 #include<stack> 3 #include<io

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

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4842 要注意题目中两点: 1.在踏入妖怪控制的区域那一刹那,先减行动力,然后才能杀妖怪 2.在妖怪控制区域行动力也会恢复 3.妖怪也许不在自己的控制区域 #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace st

zoj题目分类

饮水思源---zoj 转载自:http://bbs.sjtu.edu.cn/bbscon,board,ACMICPC,file,M.1084159773.A.html 注:所有不是太难的题都被归成了“简单题”,等到发现的时候已经太晚了,我太死脑筋 了……:( 有些题的程序我找不到了,555……:( SRbGa的题虽然都很经典……但是由于其中的大部分都是我看了oibh上的解题报告后做 的,所以就不写了…… 题目排列顺序没有规律……:( 按照个人感觉,最短路有的算做了DP,有的算做了图论. 有些比较

POJ百道水题列表

以下是poj百道水题,新手可以考虑从这里刷起 搜索1002 Fire Net1004 Anagrams by Stack1005 Jugs1008 Gnome Tetravex1091 Knight Moves1101 Gamblers1204 Additive equations 1221 Risk1230 Legendary Pokemon1249 Pushing Boxes 1364 Machine Schedule1368 BOAT1406 Jungle Roads1411 Annive

(寒假GYM开黑)2018-2019 ACM-ICPC Brazil Subregional Programming Contest

layout: post title: 2018-2019 ACM-ICPC Brazil Subregional Programming Contest author: "luowentaoaa" catalog: true tags: mathjax: true - codeforces 传送门 付队! 许老师! B.Marbles (nim博弈) 题意 一个棋盘n个点,每次可以把一个棋子移动到(x-d,y) or (x,y-d) or (x-d,y-d) 把其中一个棋子移动到(0

组队赛#1 解题总结 ZOJ 3803 YY&#39;s Minions (DFS搜索+模拟)

YY's Minions Time Limit: 2 Seconds      Memory Limit: 65536 KB Despite YY's so much homework, she would like to take some time to play with her minions first. YY lines her minions up to an N*M matrix. Every minion has two statuses: awake or asleep. W