码迷,mamicode.com
首页 > 其他好文 > 详细

[ZOJ 1009] Enigma (模拟)

时间:2014-11-17 12:18:20      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   color   ar   os   sp   for   

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

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

 

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

 

注意看这张图:

bubuko.com,布布扣

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

也就是说,无论转动轮怎么转,都能把左边的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 */

 

[ZOJ 1009] Enigma (模拟)

标签:style   blog   http   io   color   ar   os   sp   for   

原文地址:http://www.cnblogs.com/llkpersonal/p/4103135.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!