奶牛们开始对用射电望远镜扫描牧场外的宇宙感兴趣。最近,他们注意到了一种非常奇怪的脉冲调制微波从星系的中央发射出来。他们希望知道电波是否是被某些地外生命发射出来的,还是仅仅是普通的的星星发出的。
帮助奶牛们用一个能够分析他们在文件中记下的记录的工具来找到真相。他们在寻找长度在A到B之间(包含A和B本身)在每天的数据文件中重复得最多的比特序列 (1 <= A <= B <= 12)。他们在找那些重复得最多的比特序列。一个输入限制告诉你应输出多少频率最多的序列。
符合的序列可能会重叠,并且至少出现一次的序列会被计数
PROGRAM NAME: contact
INPUT FORMAT:
(file contact.in)
第一行: 三个用空格分隔的整数: A, B, N; (1 <= N < 50)
第二行及以后: 一个最多200,000字符的序列,全是0或1; 每行字符数不大于80。
OUTPUT FORMAT:
(file contact.out)
输出N个频率最高的序列(按照频率由高到低的次序)。由短到长排列频率相同的这些序列,如果长短相同,按二进制大小排列。如果出现的序列个数小于N,输出存在的序列。
对于每个存在的频率,先输出单独包含该频率的一行,再输出以空格分隔的这些序列。每行六个(除非剩下的少于六个)。
2 4 10 01010010010001000111101100001010011001111000010010011110010000000
在样例里,序列100出现了12次,而序列1000出现了5次。次数最多的序列是00,出现了23次。
23 00 15 01 10 12 100 11 11 000 001 10 010 8 0100 7 0010 1001 6 111 0000 5 011 110 1000 4 0001 0011 1100
先来解释下输出吧。
每行六个的意思是 每一种频率的后面加入跟了许多许多的01串,就六个一行,一行行的输出。
其下便是暴力的枚举了所有的情况,并按照题目要求排序输出了。
要统计字符串,最暴力还是直接 map 就好了。
代码:
/* ID:Andy Chen PROG:contact LANG:C++ */ #include <cstdio> #include <string> #include <map> #include <vector> #include <iostream> #include <algorithm> using namespace std; struct Node { string s; int cnt; Node(const string& ss="",int nn=0):s(ss),cnt(nn) {} bool operator < (const Node& a) const { if(cnt!=a.cnt) return cnt>a.cnt; if(s.size()!=a.s.size()) return s.size()<a.s.size(); return s.compare(a.s)<0; } }; string s,t; map<string,int> mp; vector<Node> ans; int a,b,n,i,num; int main() { freopen("contact.in","r",stdin); freopen("contact.out","w",stdout); cin>>a>>b>>n>>s; while(cin>>t) s+=t; while(b>=a) { for(int i=s.size()-b;i>=0;--i) { t=s.substr(i,b); if(mp[t]==0) ans.push_back(Node(t)); ++mp[t]; } --b; } for(i=0;i<ans.size();++i) ans[i].cnt=mp[ans[i].s]; sort(ans.begin(),ans.end()); i=0; while(n--) { if(i==ans.size()) break; cout<<ans[i].cnt<<"\n"<<ans[i].s; num=1; while(++i<ans.size()&&ans[i].cnt==ans[i-1].cnt) {//仅是为了输出而已。。搞这么复杂 if(num==6) { cout<<"\n"; num=0; } else cout<<" "; cout<<ans[i].s; ++num; } cout<<"\n"; } return 0; }
原文:http://www.cnblogs.com/cherry231/p/5185331.html