hehe.....
第一遍看完题目时,完全没看明白什么意思,就直接看输入输出去了。猜到个大致意思了,然后才看题的。
懂了后,第一想法是觉得这题目很难,有点不太想做了,因为最近做USACO上的题目,基本每个都得花一两天。难受啊。。。
后来出去走走,回来一坐下,马上就有想法了。。。。01010101010太好压缩了吧。。。
Three space-separated integers: A, B, N; (1 <= N < 50)(1 <= A <= B <= 12)
搜索的连续子串最大长度才12,2^12=4096,可以开个12*4096的数组用来记录出现次数。所有的情况最多也就2*10^5*12 = 10^6,可以枚举下。
代码如下:
/*
ID: guo geer
PROG: contact
LANG: C++
*/
#include<iostream>
#include<cstring>
#include<fstream>
using namespace std;
#define M 12
#define N 4096
int res[M+1][N+1]; //2^12 = 4096
int bin[M+1];
#define LENGTH 200000
char input[LENGTH + 1];
int main()
{
ofstream fout("contact.out");
ifstream fin("contact.in");
int i,j,k;
bin[0] = 1;
for(i=1; i<=M; i++)
bin[i] = 2*bin[i-1];
int a, b, n;
while(fin>>a>>b>>n)
{
input[0] = '\0';
char str[81];
while(fin>>str)
{
strcat(input, str);
if(strlen(str) < 80)
break;
}
for(i=0; i<=M; i++)
for(j=0; j<=N; j++)
res[i][j] = 0;
for(i=0; input[i] != '\0'; i++)
{
int sum = 0;
for(j=0; j<12 && input[i+j] != '\0'; j++)
{
sum = sum * 2 + input[i+j] - '0';
res[j+1][sum] ++;
}
}
int Max = 0;
for(i=a; i<=b; i++)
for(j=0; j<bin[i]; j++)
if(Max < res[i][j])
Max = res[i][j];
int count = 0;
for(i=Max; i> 0 && count < n; i--)
{
int kk = 0;
for(j=a; j<=b && count < n; j++)
for(k=0; k<=bin[j] && count < n; k++)
if(res[j][k] == i)
{
kk ++;
int x;
if(kk == 1)
fout<<i<<endl;
if(kk != 1 && kk % 6 == 1)
fout<<'\n';
if(kk % 6 != 1)
fout<<' ';
for(x = 1; x<=j; x++)
if(bin[j-x]&k)
fout<<'1';
else fout << '0';
}
if(kk != 0)
{
fout<<endl;
count ++;
}
}
}
return 0;
}