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

poj1026 Cipher

时间:2015-08-17 23:32:26      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:

题目意思可概括为给定集合S = {1,..,n}的一个双射关系f, 求经过k次复合之后元素i对应的元素fk(i) (i∈S)。

由于函数是双射,一个原像对应唯一一个像,同样一个像有唯一一个原像,考虑整个映射关系,存在整数m∈ Z,使得fm=f0=I。

即具有周期性。

每个元素映射回它自己有独立的周期T(i),整个映射的周期T=lcm(T(i)), i ∈ S。

独立处理更快,但对于本题也是刚刚卡过。

当然如果事先把所有询问读入加以预处理或者直接全部预处理会更快。

样例代码860ms卡过。

 

http://poj.org/problem?id=1026
 
技术分享
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 
 5 using namespace std;
 6 
 7 const int maxn = 200 + 10;
 8 int n;
 9 char s[maxn];
10 int f[maxn];
11 int period[maxn];
12 int repeats;
13 
14 struct Node{
15     int from, to;
16 }node[maxn];
17 
18 int gcd(int a, int b){
19     if(!b) return a;
20     return gcd(b, a % b);
21 }
22 
23 bool cmp(Node a, Node b){
24     return a.to < b.to;
25 }
26 
27 void init(){
28     for(int i = 0; i < n; i++){
29         int t = f[i], cnt = 1;
30         while(i != t) t = f[t], ++cnt;
31         period[i] = cnt;
32     }
33 }
34 
35 void solve(){
36     for(int i = 0; i < n; i++) node[i].from = node[i].to = i;
37     for(int i = 0; i < n; i++){
38         int p1 = repeats % period[i];
39         while(p1--) node[i].to = f[node[i].to];
40     }
41     sort(node, node + n, cmp);
42     for(int i = 0; i < n; i++) printf("%c", s[node[i].from]);
43     printf("\n");
44 }
45 
46 int main(){
47     while(~scanf("%d", &n) && n){
48         for(int i = 0, j; i < n; i++){
49             scanf("%d", &j);
50             f[i] = j - 1;
51         }
52         init();
53         while(~scanf("%d", &repeats) && repeats){
54             getchar();
55             gets(s);
56             int len = strlen(s);
57             for(int i = len; i < n; i++) s[i] =  ;
58             s[n] = \0;
59             solve();
60         }
61         printf("\n");
62     }
63     return 0;
64 }
View Code

 

poj1026 Cipher

标签:

原文地址:http://www.cnblogs.com/astoninfer/p/4737986.html

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