/* 2011-09-30
自己的hash函数模板
zoj3013 hash映射: T = 200
zoj3013 字典树: T = 80
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define min( a, b ) ((a)<(b)?(a):(b))
/* Hash define */
#define wordsize 10
#define nodesize 12501
#define hashsize 100000
typedef struct node
{
char word[ wordsize ];
node* next;
}list;
list dict[ nodesize+1 ];
list* head[ hashsize+1 ];
class Hash
{
private:
static int mul[ 8 ];
int size;
public:
Hash(){size = 0;memset( head, 0, sizeof( head ) );}
int hash( char* word, int l ) {
int value = 0;
for ( int i = 0 ; i < l ; ++ i )
value = (value+word[ i ]*mul[ i ])%hashsize;
return value;
}
void insert( char* word, int l ) {
int id = hash( word, l );
for ( int i = 0 ; i < l ; ++ i )
dict[ size ].word[ i ] = word[ i ];
dict[ size ].word[ l ] = ‘\0‘;
dict[ size ].next = head[ id ];
head[ id ] = &(dict[ size ++ ]);
}
bool find( char* word, int l ) {
int i,id = hash( word, l );
for ( list* p = head[ id ] ; p ; p = p->next ) {
for ( i = 0 ; i < l ; ++ i )
if ( word[ i ] != p->word[ i ] ) break;
if ( i == l ) return true;
}return false;
}
};
int Hash::mul[ 8 ] = {31,131,313,1313,3131,13131,31313,131313};
/* Hash end */
char word[ 12500 ][ 10 ];
char pass[ 100 ][ 4105 ];
int last[ 4105 ];
int shor[ 4105 ];
void output( int s, char* p, int L )
{
if ( s < 0 ) return;
output( last[ s ], p, L );
for ( int i = last[ s ]+1 ; i <= s ; ++ i )
printf("%c",p[ i ]);
if ( s < L ) printf("#");
else printf("\n");
}
int main()
{
int m,n;
while ( scanf("%d%d",&m,&n) != EOF ) {
for ( int i = 0 ; i < m ; ++ i )
scanf("%s",word[ i ]);
for ( int i = 0 ; i < n ; ++ i )
scanf("%s",pass[ i ]);
Hash trie;
for ( int i = 0 ; i < m ; ++ i )
trie.insert( word[ i ], strlen( word[ i ] ) );
for ( int i = 0 ; i < n ; ++ i ) {
int L = strlen( pass[ i ] );
for ( int j = 0 ; j < L ; ++ j ) {
last[ j ] = -1;
shor[ j ] = L+1;
}shor[ 0 ] = 1;
for ( int j = 0 ; j < L ; ++ j ) {
for ( int l = 1 ; l <= 8 ; ++ l )
if ( trie.find( &pass[ i ][ j ], min( l, L-j ) ) ) {
int tail = j+min( l, L-j )-1;
if ( j && shor[ tail ] <= shor[ j-1 ] ) continue;
if ( !j && shor[ tail ] > shor[ j-1 ] ) shor[ tail ] = 0;
else shor[ tail ] = shor[ j-1 ];
last[ tail ] = j-1;
}
if ( j > 0 && shor[ j ] > shor[ j-1 ]+1 ) {
shor[ j ] = shor[ j-1 ]+1;
last[ j ] = j-1;
}
}
printf("%d\n",shor[ L-1 ]);
output( L-1, pass[ i ], L-1 );
}
}
return 0;
}
原文:http://blog.csdn.net/mobius_strip/article/details/21910053