#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
#include <cassert>
using namespace std;
// Letter-Frequency pair
typedef pair< char , float > pair_lf;
void print( const vector< pair_lf> & vec)
{
for ( const pair_lf item : vec)
{
cout << item.first << ": " << item.second << endl;
}
}
enum class EMove
{
N,
NE,
E,
SE,
S,
SW,
W,
NW,
Last,
First = N,
} ;
inline EMove operator++ ( EMove& x ) { return x = ( EMove) ( std:: underlying_type < EMove> :: type ( x) + 1 ) ; }
EMove operator* ( EMove c) { return c; }
EMove begin( EMove r) { return EMove:: First ; }
EMove end( EMove r) { return EMove:: Last ; }
int move( const unsigned int & start, const unsigned int & w, const unsigned int & h, const EMove & m)
{
switch ( m)
{
case EMove:: N :
if ( start < w)
{
return - 1 ;
} else {
return start - w;
}
break ;
case EMove:: NE :
if ( start < w || ( ( start + 1 ) % w == 0 ) )
{
return - 1 ;
} else {
return start - w + 1 ;
}
break ;
case EMove:: E :
if ( ( start + 1 ) % w == 0 )
{
return - 1 ;
} else {
return start + 1 ;
}
break ;
case EMove:: SE :
if ( ( ( start + w) > ( w * h - 1 ) ) || ( ( start + 1 ) % w == 0 ) )
{
return - 1 ;
} else {
return start + w + 1 ;
}
break ;
case EMove:: S :
if ( ( start + w) > ( w * h - 1 ) )
{
return - 1 ;
} else {
return start + w;
}
break ;
case EMove:: SW :
if ( ( start + w) > ( w * h - 1 ) || ( start % w == 0 ) )
{
return - 1 ;
} else {
return start + w - 1 ;
}
break ;
case EMove:: W :
if ( start % w == 0 )
{
return - 1 ;
} else {
return start - 1 ;
}
break ;
case EMove:: NW :
if ( ( start % w == 0 ) || ( start < w) )
{
return - 1 ;
} else {
return start - w - 1 ;
}
break ;
}
assert ( false ) ;
return - 1 ;
}
bool verify_word( const vector< char > & grid, const unsigned int & w, const unsigned int & h, vector< bool > visited, const string & word, int start)
{
if ( start == - 1 )
{
for ( int y = 0 ; y < h; y++ )
{
for ( int x = 0 ; x < w; x++ )
{
const int new_start = y * w + x;
bool found = verify_word( grid, w, h, visited, word, new_start) ;
if ( found)
{
return true ;
}
}
}
return false ;
}
if ( visited[ start] )
{
return false ;
}
const unsigned int length = word.length ( ) ;
if ( grid[ start] == word[ length - 1 ] )
{
if ( length == 1 )
{
return true ;
} else {
const string new_word = word.substr ( 0 , length - 1 ) ;
vector< bool > new_visited = visited;
new_visited[ start] = true ;
for ( EMove m : EMove( ) )
{
int new_start = move( start, w, h, m) ;
if ( new_start == - 1 )
{
continue ;
}
bool found = verify_word( grid, w, h, new_visited, new_word, new_start) ;
if ( found)
{
return true ;
}
}
return false ;
}
} else {
return false ;
}
}
int main( )
{
vector< pair_lf> letter_freqs;
int count;
cin >> count;
for ( int i = 0 ; i < count; i++ )
{
char letter;
float freq;
cin >> letter >> freq;
letter_freqs.push_back ( make_pair( letter, freq / 100 .f ) ) ;
}
struct {
bool operator( ) ( const pair_lf left, const pair_lf right)
{
return left.second < right.second ;
}
} pairwise_comparator;
sort( letter_freqs.begin ( ) , letter_freqs.end ( ) , pairwise_comparator) ;
vector< pair_lf> bucketed_letters;
float sum = 0 .f ;
for ( const pair_lf & item : letter_freqs)
{
sum + = item.second ;
bucketed_letters.push_back ( make_pair( item.first , sum) ) ;
}
//cout << "sum: " << sum << endl;
random_device rd;
int seed = rd( ) ;
seed = - 740863471 ;
cout << "seed: " << seed << endl;
mt19937 gen( seed) ;
vector< char > sampled_letters;
int w, h;
cin >> w >> h;
const int grid_size = w * h;
//print(bucketed_letters);
for ( int i = 0 ; i < grid_size; i++ )
{
const float sample = generate_canonical< float , 10 > ( gen) ;
int bucket = 0 ;
while ( sample > bucketed_letters[ bucket] .second )
{
bucket++ ;
}
assert ( bucket < 26 ) ;
const auto letter = bucketed_letters[ bucket] .first ;
sampled_letters.push_back ( letter) ;
}
for ( int y = 0 ; y < h; y++ )
{
for ( int x = 0 ; x < w; x++ )
{
cout << sampled_letters[ y * w + x] << ' ' ;
}
cout << endl;
}
vector< bool > visited( grid_size, false ) ;
while ( cin )
{
string word;
cin >> word;
const int length = word.length ( ) ;
if ( length >= 4 && length < grid_size)
{
bool found = verify_word( sampled_letters, w, h, visited, word, - 1 ) ;
if ( found)
{
cout << "found " << word << endl;
}
}
}
return 0 ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8cmFuZG9tPgojaW5jbHVkZSA8Y2Fzc2VydD4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgovLyBMZXR0ZXItRnJlcXVlbmN5IHBhaXIKdHlwZWRlZiBwYWlyPGNoYXIsIGZsb2F0PiBwYWlyX2xmOwoKdm9pZCBwcmludChjb25zdCB2ZWN0b3I8cGFpcl9sZj4gJnZlYykKewoJZm9yIChjb25zdCBwYWlyX2xmIGl0ZW0gOiB2ZWMpCgl7CgkJY291dCA8PCBpdGVtLmZpcnN0IDw8ICI6ICIgPDwgaXRlbS5zZWNvbmQgPDwgZW5kbDsKCX0KfQoKZW51bSBjbGFzcyBFTW92ZQp7CglOLAoJTkUsCglFLAoJU0UsCglTLAoJU1csCglXLAoJTlcsCglMYXN0LAoJRmlyc3QgPSBOLAp9OwoKaW5saW5lIEVNb3ZlIG9wZXJhdG9yKysoIEVNb3ZlJiB4ICkgeyByZXR1cm4geCA9IChFTW92ZSkoc3RkOjp1bmRlcmx5aW5nX3R5cGU8RU1vdmU+Ojp0eXBlKHgpICsgMSk7IH0KRU1vdmUgb3BlcmF0b3IqKEVNb3ZlIGMpIHtyZXR1cm4gYzt9IApFTW92ZSBiZWdpbihFTW92ZSByKSB7cmV0dXJuIEVNb3ZlOjpGaXJzdDt9CkVNb3ZlIGVuZChFTW92ZSByKSAgIHtyZXR1cm4gRU1vdmU6Okxhc3Q7fQoKaW50IG1vdmUoY29uc3QgdW5zaWduZWQgaW50ICZzdGFydCwgY29uc3QgdW5zaWduZWQgaW50ICZ3LCBjb25zdCB1bnNpZ25lZCBpbnQgJmgsIGNvbnN0IEVNb3ZlICZtKQp7Cglzd2l0Y2ggKG0pCgl7CgkJY2FzZSBFTW92ZTo6TjoKCQkJaWYgKHN0YXJ0IDwgdykKCQkJewoJCQkJcmV0dXJuIC0xOwoJCQl9IGVsc2UgewoJCQkJcmV0dXJuIHN0YXJ0IC0gdzsKCQkJfQoJCQlicmVhazsKCQljYXNlIEVNb3ZlOjpORToKCQkJaWYgKHN0YXJ0IDwgdyB8fCAoKHN0YXJ0ICsgMSkgJSB3ID09IDApKQoJCQl7CgkJCQlyZXR1cm4gLTE7CgkJCX0gZWxzZSB7CgkJCQlyZXR1cm4gc3RhcnQgLSB3ICsgMTsKCQkJfQoJCQlicmVhazsKCQljYXNlIEVNb3ZlOjpFOgoJCQlpZiAoKHN0YXJ0ICsgMSkgJSB3ID09IDApCgkJCXsKCQkJCXJldHVybiAtMTsKCQkJfSBlbHNlIHsKCQkJCXJldHVybiBzdGFydCArIDE7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSBFTW92ZTo6U0U6CgkJCWlmICgoKHN0YXJ0ICsgdykgPiAodyAqIGggLSAxKSkgfHwgKChzdGFydCArIDEpICUgdyA9PSAwKSkKCQkJewoJCQkJcmV0dXJuIC0xOwoJCQl9IGVsc2UgewoJCQkJcmV0dXJuIHN0YXJ0ICsgdyArIDE7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSBFTW92ZTo6UzoKCQkJaWYgKChzdGFydCArIHcpID4gKHcgKiBoIC0gMSkpCgkJCXsKCQkJCXJldHVybiAtMTsKCQkJfSBlbHNlIHsKCQkJCXJldHVybiBzdGFydCArIHc7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSBFTW92ZTo6U1c6CgkJCWlmICgoc3RhcnQgKyB3KSA+ICh3ICogaCAtIDEpIHx8IChzdGFydCAlIHcgPT0gMCkpCgkJCXsKCQkJCXJldHVybiAtMTsKCQkJfSBlbHNlIHsKCQkJCXJldHVybiBzdGFydCArIHcgLSAxOwoJCQl9CgkJCWJyZWFrOwoJCWNhc2UgRU1vdmU6Olc6CgkJCWlmIChzdGFydCAlIHcgPT0gMCkKCQkJewoJCQkJcmV0dXJuIC0xOwoJCQl9IGVsc2UgewoJCQkJcmV0dXJuIHN0YXJ0IC0gMTsKCQkJfQoJCQlicmVhazsKCQljYXNlIEVNb3ZlOjpOVzoKCQkJaWYgKChzdGFydCAlIHcgPT0gMCkgfHwgKHN0YXJ0IDwgdykpCgkJCXsKCQkJCXJldHVybiAtMTsKCQkJfSBlbHNlIHsKCQkJCXJldHVybiBzdGFydCAtIHcgLSAxOwoJCQl9CgkJCWJyZWFrOwoJfQoJYXNzZXJ0KGZhbHNlKTsKCXJldHVybiAtMTsKfQoKYm9vbCB2ZXJpZnlfd29yZChjb25zdCB2ZWN0b3I8Y2hhcj4gJmdyaWQsIGNvbnN0IHVuc2lnbmVkIGludCAmdywgY29uc3QgdW5zaWduZWQgaW50ICZoLCB2ZWN0b3I8Ym9vbD4gdmlzaXRlZCwgY29uc3Qgc3RyaW5nICZ3b3JkLCBpbnQgc3RhcnQpCnsKCWlmIChzdGFydCA9PSAtMSkKCXsKCQlmb3IgKGludCB5ID0gMDsgeSA8IGg7IHkrKykKCQl7CgkJCWZvciAoaW50IHggPSAwOyB4IDwgdzsgeCsrKQoJCQl7CgkJCQljb25zdCBpbnQgbmV3X3N0YXJ0ID0geSAqIHcgKyB4OwoJCQkJYm9vbCBmb3VuZCA9IHZlcmlmeV93b3JkKGdyaWQsIHcsIGgsIHZpc2l0ZWQsIHdvcmQsIG5ld19zdGFydCk7CgkJCQlpZiAoZm91bmQpCgkJCQl7CgkJCQkJcmV0dXJuIHRydWU7CgkJCQl9CgkJCX0KCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQoJaWYgKHZpc2l0ZWRbc3RhcnRdKQoJewoJCXJldHVybiBmYWxzZTsKCX0KCWNvbnN0IHVuc2lnbmVkIGludCBsZW5ndGggPSB3b3JkLmxlbmd0aCgpOwoJaWYgKGdyaWRbc3RhcnRdID09IHdvcmRbbGVuZ3RoIC0gMV0pCgl7CgkJaWYgKGxlbmd0aCA9PSAxKQoJCXsKCQkJcmV0dXJuIHRydWU7CgkJfSBlbHNlIHsKCQkJY29uc3Qgc3RyaW5nIG5ld193b3JkID0gd29yZC5zdWJzdHIoMCwgbGVuZ3RoIC0gMSk7CgkJCXZlY3Rvcjxib29sPiBuZXdfdmlzaXRlZCA9IHZpc2l0ZWQ7CgkJCW5ld192aXNpdGVkW3N0YXJ0XSA9IHRydWU7CgkJCWZvciAoRU1vdmUgbSA6IEVNb3ZlKCkpCgkJCXsKCQkJCWludCBuZXdfc3RhcnQgPSBtb3ZlKHN0YXJ0LCB3LCBoLCBtKTsKCQkJCWlmIChuZXdfc3RhcnQgPT0gLTEpCgkJCQl7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQlib29sIGZvdW5kID0gdmVyaWZ5X3dvcmQoZ3JpZCwgdywgaCwgbmV3X3Zpc2l0ZWQsIG5ld193b3JkLCBuZXdfc3RhcnQpOwoJCQkJaWYgKGZvdW5kKQoJCQkJewoJCQkJCXJldHVybiB0cnVlOwoJCQkJfQoJCQl9CgkJCXJldHVybiBmYWxzZTsKCQl9Cgl9IGVsc2UgewoJCXJldHVybiBmYWxzZTsKCX0KfQoKaW50IG1haW4oKQp7Cgl2ZWN0b3I8cGFpcl9sZj4gbGV0dGVyX2ZyZXFzOwoJaW50IGNvdW50OwoJY2luID4+IGNvdW50OwoJZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKQoJewoJCWNoYXIgbGV0dGVyOwoJCWZsb2F0IGZyZXE7CgkJY2luID4+IGxldHRlciA+PiBmcmVxOwoJCWxldHRlcl9mcmVxcy5wdXNoX2JhY2sobWFrZV9wYWlyKGxldHRlciwgZnJlcSAvIDEwMC5mKSk7Cgl9CglzdHJ1Y3QgewoJCWJvb2wgb3BlcmF0b3IoKShjb25zdCBwYWlyX2xmIGxlZnQsIGNvbnN0IHBhaXJfbGYgcmlnaHQpCgkJewoJCQlyZXR1cm4gbGVmdC5zZWNvbmQgPCByaWdodC5zZWNvbmQ7CgkJfQoJfSBwYWlyd2lzZV9jb21wYXJhdG9yOwoJc29ydChsZXR0ZXJfZnJlcXMuYmVnaW4oKSwgbGV0dGVyX2ZyZXFzLmVuZCgpLCBwYWlyd2lzZV9jb21wYXJhdG9yKTsKCXZlY3RvcjxwYWlyX2xmPiBidWNrZXRlZF9sZXR0ZXJzOwoJZmxvYXQgc3VtID0gMC5mOwoJZm9yIChjb25zdCBwYWlyX2xmICZpdGVtIDogbGV0dGVyX2ZyZXFzKQoJewoJCXN1bSArPSBpdGVtLnNlY29uZDsKCQlidWNrZXRlZF9sZXR0ZXJzLnB1c2hfYmFjayhtYWtlX3BhaXIoaXRlbS5maXJzdCwgc3VtKSk7Cgl9CgkvL2NvdXQgPDwgInN1bTogIiA8PCBzdW0gPDwgZW5kbDsKCXJhbmRvbV9kZXZpY2UgcmQ7CglpbnQgc2VlZCA9IHJkKCk7CglzZWVkID0gLTc0MDg2MzQ3MTsKCWNvdXQgPDwgInNlZWQ6ICIgPDwgc2VlZCA8PCBlbmRsOwoJbXQxOTkzNyBnZW4oc2VlZCk7Cgl2ZWN0b3I8Y2hhcj4gc2FtcGxlZF9sZXR0ZXJzOwoJaW50IHcsIGg7CgljaW4gPj4gdyA+PiBoOwoJY29uc3QgaW50IGdyaWRfc2l6ZSA9IHcgKiBoOwoJLy9wcmludChidWNrZXRlZF9sZXR0ZXJzKTsKCWZvciAoaW50IGkgPSAwOyBpIDwgZ3JpZF9zaXplOyBpKyspCgl7CgkJY29uc3QgZmxvYXQgc2FtcGxlID0gZ2VuZXJhdGVfY2Fub25pY2FsPGZsb2F0LCAxMD4oZ2VuKTsKCQlpbnQgYnVja2V0ID0gMDsKCQl3aGlsZSAoc2FtcGxlID4gYnVja2V0ZWRfbGV0dGVyc1tidWNrZXRdLnNlY29uZCkKCQl7CgkJCWJ1Y2tldCsrOwoJCX0KCQlhc3NlcnQoYnVja2V0IDwgMjYpOwoJCWNvbnN0IGF1dG8gbGV0dGVyID0gYnVja2V0ZWRfbGV0dGVyc1tidWNrZXRdLmZpcnN0OwoJCXNhbXBsZWRfbGV0dGVycy5wdXNoX2JhY2sobGV0dGVyKTsKCX0KCWZvciAoaW50IHkgPSAwOyB5IDwgaDsgeSsrKQoJewoJCWZvciAoaW50IHggPSAwOyB4IDwgdzsgeCsrKQoJCXsKCQkJY291dCA8PCBzYW1wbGVkX2xldHRlcnNbeSAqIHcgKyB4XSA8PCAnICc7CgkJfQoJCWNvdXQgPDwgZW5kbDsKCX0KCXZlY3Rvcjxib29sPiB2aXNpdGVkKGdyaWRfc2l6ZSwgZmFsc2UpOwoJd2hpbGUgKGNpbikKCXsKCQlzdHJpbmcgd29yZDsKCQljaW4gPj4gd29yZDsKCQljb25zdCBpbnQgbGVuZ3RoID0gd29yZC5sZW5ndGgoKTsKCQlpZiAobGVuZ3RoID49IDQgJiYgbGVuZ3RoIDwgZ3JpZF9zaXplKQoJCXsKCQkJYm9vbCBmb3VuZCA9IHZlcmlmeV93b3JkKHNhbXBsZWRfbGV0dGVycywgdywgaCwgdmlzaXRlZCwgd29yZCwgLTEpOwoJCQlpZiAoZm91bmQpCgkJCXsKCQkJCWNvdXQgPDwgImZvdW5kICIgPDwgd29yZCA8PCBlbmRsOwoJCQl9CgkJfQoJfQoJcmV0dXJuIDA7Cn0K