Sereja ans Anagrams

Codeforces Round #215 (Div. 1) B:http://codeforces.com/problemset/problem/367/B

题意:给你两个序列a,b,然后给你一个数p,然后让你在a序列中找一个位置q,得以这个位置开始,以后每隔着aq+aq+1*(p)+.......aq+(m-1)*p,这个序列经过重新排序能够等于b,输出,所有的这样的位置。

题解:可以采用递推。先找起点是1,然后再找起点是1+p,找1+p的时候,其实只要在找1的基础上删除最前的那个数,然后再加入一个数就可以了。一次类推,然后,找2开头,2+开头。具体实现的时候,可以看下面代码。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<map>
 6 using namespace std;
 7 const int N=4e5+10;
 8 int a[N],b[N];//记录a,b,序列
 9 int counts[N],ans[N];//counts统计b序列数字出现的次数
10 int n,m,p,cnt,top;
11 int main(){
12   while(~scanf("%d%d%d",&n,&m,&p)){
13          map<int,int>Qa;//离散化
14         memset(counts,0,sizeof(counts));
15         memset(a,-1,sizeof(a));
16         memset(b,-1,sizeof(b));
17         cnt=top=0;
18         for(int i=1;i<=n;i++){
19             scanf("%d",&a[i]);
20             if(Qa[a[i]]==0)Qa[a[i]]=++cnt;
21         }
22         cnt=0;bool flag=false;
23         for(int i=1;i<=m;i++){
24             scanf("%d",&b[i]);
25             if(Qa[b[i]]==0){//如果b序列中数在a中没有出现,就直接不用找了
26                 flag=true;
27             }
28             counts[Qa[b[i]]]++;//统计b中数字出现的次数
29         }
30         if(!flag){
31         for(int i=1;i<=p;i++){
32             int ct=0,sum0=0;//每次查询记录b中数字在a中出现的次数,如果出现m次,说明等于b序列
33             for(int j=i;j<=n*2;j+=p){//注意这里是j<=2*n,虽然在n+1以后的数不会构成b序列,但是这里是为了把之前加入放入数都还原,便于下一次使用
34                 counts[Qa[a[j]]]--;//入队之后次数减一
35                 ct++;
36                 if(counts[Qa[a[j]]]>=0)//如果次数在-1的基础上任然大于0,说明,这个数字是b中的数字
37                     sum0++;//注意判断是要求大于0的,因为b的数字可能会重复
38                 if(ct==m){//判断第一次达到m个数是否满足条件
39                     if(sum0==m)
40                         ans[++top]=i;
41                 }
42                 else if(ct>m){//当多余m个时候,就要把最前面的数删除,只保留m个数
43                     if(counts[Qa[a[i+(ct-1-m)*p]]]>=0){//如果这个数次数大于=0,说明这个数被统计过,所以要还原
44                         sum0--;
45                         counts[Qa[a[i+(ct-1-m)*p]]]++;
46                     }
47                     else{
48                         counts[Qa[a[i+(ct-1-m)*p]]]++;
49                     }
50                     if(sum0==m){//判断新加入过的数有没有满足条件
51                         ans[++top]=i+(ct-m)*p;
52                     }
53                 }
54             }
55         }
56     }
57        sort(ans+1,ans+top+1);
58        printf("%d\n",top);
59        for(int i=1;i<top;i++)
60          printf("%d ",ans[i]);
61          if(top>0)
62         printf("%d\n",ans[top]);
63         else
64         printf("\n");
65   }
66 }
View Code

 

posted on 2014-08-06 11:04  天依蓝  阅读(141)  评论(0编辑  收藏  举报

导航