剛開始做這題的時候思路錯了, 把他想成字串模式比對題了。通過構建長度在[A,B]之間的字串,然後再對主字串進行模式比對,想想要用kmp演算法,對於這個我還不是很懂.... 打算好好學習一下kmp,後來估計了一下時間,發現必須逾時。
轉而一想:
其實需要的只是在主字串中的一些子集,通過直接遍曆主字串長度為len(A<=len<=B),把這個數讀出來,相應的+1就好。通過這種思路,寫完代碼。後發現,對於len=2,選項='00'和len=1,選項='0',都會被歸為一類,明顯這樣不符合題意。
怎麼解決呢?
可以通過添加前置'1',區別開來。再在輸出的時候忽略前置'1'。
另外用到了排序,將出現頻率分別開來。
輸出的code寫得不是很好;
/*ID:sevenst4LANG:C++PROG:contact*/#include<stdio.h>#include<algorithm>using namespace std;int cnt[10000];int cp[10000];char line[222222];bool cmp( int a,int b ){ return a>b; };void print( int num ){ int l=0; int k[15]={0}; while( num ) { k[l++]=num&1;num=num>>1; } for( int i=l-2;i>=0;i-- ) printf( "%d",k[i] );}int getnum( int s,int e ){ int ret=0; for( int i=s;i<e;i++ ) if( line[i]=='1' ) ret=ret<<1|1; else ret=ret<<1;return ret;}int main(){ freopen( "contact.in","r",stdin ); freopen( "contact.out","w",stdout ); int A,B,N; for( int i=0;i<(1<<13);i++ ) cnt[i]=0; scanf( "%d %d %d",&A,&B,&N ); char data[80]; int len=0; while( scanf( "%s",&data )!=EOF ) { for( int i=0;data[i]!='\0';i++ ) line[len++]=data[i]; } for( int i=A;i<=B;i++ ) { for( int j=0;j+i<=len;j++ ) cnt[(1<<i)+getnum(j,j+i)]++;}for( int i=0;i<(1<<(B+1));i++ ) cp[i]=cnt[i]; sort( cp,cp+(1<<(B+1)),cmp );int index=0;while( N-- ){ int top=cp[index]; if( top==0 ) break; int outnum=0; printf( "%d\n",top ); bool flag=false; for( int i=0;i<(1<<(B+1));i++ ) if( cnt[i]==top ) { outnum++; if( outnum!=1 ) printf( " " );//不是第一個有前置空格 print( i ); if( outnum==6 )//第六個有斷行符號{ outnum=0; printf( "\n" );} index++;} if( outnum!=0 ) printf( "\n" ); } return 0;}