0w1

ABC 030 D - 語呂合わせ ( Enumeration )

D: 語呂合わせ - AtCoder Beginner Contest 031 | AtCoder
Since there are only 9 s, each |s| within range [ 1, 3 ], we can enumerate in 3^9. Then check whether it is valid with O( N ).
Total ( 3^9 * N ).

const int MAXK = 9 + 1;
const int MAXN = 50 + 2;

int K, N;
string nums[ MAXN ], word[ MAXN ];

bool ok( int S, bool show ){
    int t = S;
    vi len( K );
    for( int i = 0; i < K; ++i )
        len[ i ] = S % 3 + 1,
        S /= 3;
    map< int, string > i2s;
    for( int i = 0; i < N; ++i ){
        int len_sum = 0;
        for( int j = 0; j < nums[ i ].size(); ++j )
            len_sum += len[ nums[ i ][ j ] - '0' - 1 ];
        if( len_sum != word[ i ].size() ) return false;
        for( int j = 0, k = 0; j < nums[ i ].size(); ++j ){
            int d = nums[ i ][ j ] - '0' - 1;
            string ns = word[ i ].substr( k, len[ d ] );
            if( i2s.count( d ) and i2s[ d ] != ns ) return false;
            i2s[ d ] = ns;
            k += len[ d ];
        }
    }
    if( show ){
        for( int i = 0; i < K; ++i )
            cout << i2s[ i ] << "\n";
    }
    return true;
}

void solve(){
    cin >> K >> N;
    for( int i = 0; i < N; ++i )
        cin >> nums[ i ] >> word[ i ];
    int S = 1; for( int i = 0; i < K; ++i ) S *= 3;
    for( int i = 0; i < S; ++i )
        if( ok( i, false ) )
            return ( void ) ok( i, true );
}