【BZOJ 4104】 4104: [Thu Summer Camp 2015]解密运算 (智商)

4104: [Thu Summer Camp 2015]解密运算

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 370  Solved: 237

Description

 对于一个长度为N的字符串,我们在字符串的末尾添加一个特殊的字符"."。之后将字符串视为一个环,从位置1,2,3,...,N+1为起点读出N+1个字符,就能得到N+1个字符串。

比如对于字符串“ABCAAA”,我们可以得到这N+1个串:
ABCAAA.
BCAAA.A
CAAA.AB
AAA.ABC
AA.ABCA
A.ABCAA
.ABCAAA
接着我们对得到的这N+1个串按字典序从小到大进行排序(注意特殊字符“.”的字典序小于任何其他的字符)结果如下:
.ABCAAA
A.ABCAA
AA.ABCA
AAA.ABC
ABCAAA.
BCAAA.A
CAAA.AB
最后,将排序好的N+1个串的最后一个字符取出,按照顺序排成一个新的字符串,也就是上面这个表的最后一列,就是加密后的密文“AAAC.AB”。
请通过加密后的密文求出加密前的字符串。

Input

第一行有两个整数N,M,分别表示加密前的字符串长度和字符集大小,其中字符用整数1,2,3,...,M编号,添加的特殊字符“."用0编号。
第二行为N+1个整数,表示加密后的字符串。

Output

输出仅一行,包含N个整数,用空格隔开,依次表示加密前字符串中每个字符的编号。

Sample Input

6 3
1 1 1 3 0 1 2

Sample Output

1 2 3 1 1 1

HINT

 #i (i=1~4)    N=5*(i+1) M<=3



#5~6    N,M<=50 字符串中字符互不相同


#7~8    N,M<=1000 字符串中字符互不相同


#9~12    N,M<=1000


#13~#20    N,M<=200000

Source

 

【分析】

  其实是好分析的,我太蠢了。

  看样例:【图画得我好辛苦啊】

  

  你知道最后一列的,就知道了元素的组成,还有*的位置你就知道第一个数排第几,你可以得出第一位是A。

  但是是哪个A呢?给出的序列有4个A,前4个字符串的第一位都是A,而这个A排在第四位,说明他后面的字符串跟前面的比是最大的。

  

  而对于后面的字符串的比较其实序列也已经给出,看上图,红框的是一样的,他其实已经给你排好序了。

  所以,这个A就是加密序列中的第四个A!

  以此类推,可以知道第二个字符排第几,可以求出整个序列了。

  

  具体做法看代码,真心短。

 

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 #define Maxn 200010
 8 
 9 struct node{int x,id;}t[Maxn];
10 bool cmp(node x,node y) {return x.x==y.x?x.id<y.id:x.x<y.x;}
11 
12 int main()
13 {
14     int n,m;
15     scanf("%d%d",&n,&m);
16     for(int i=0;i<=n;i++)
17     {
18         scanf("%d",&t[i].x);
19         t[i].id=i;
20     }
21     sort(t,t+1+n,cmp);
22     int nw=t[0].id;
23     for(int i=1;i<=n;i++)
24     {
25         printf("%d ",t[nw].x);
26         nw=t[nw].id;
27     }
28     return 0;
29 }
View Code

 

2017-04-08 15:47:56

posted @ 2017-04-08 15:47  konjak魔芋  阅读(380)  评论(0编辑  收藏  举报