HDU 4474 Yet Another Multiple Problem ( BFS + 同余剪枝 )

没什么巧办法,直接搜就行。

用余数作为每个节点的哈希值。

#include <cstdio>

#include <cstring>

#include <cstdlib>



const int MAXN = 10100;



struct node

{

    int mod;

    int fa;

    int digit;

    node() {}

    node( int mod, int fa, int dig ):mod(mod), fa(fa), digit(dig) { }

};



int N;

bool ok[12];

bool vis[MAXN];

node Q[MAXN << 2];



void findFa( int u )

{

    if ( u == -1 ) return;

    findFa( Q[u].fa );

    printf( "%d", Q[u].digit );

}



int BFS()

{

    int head = 0;

    int tail = 0;

    memset( vis, false, sizeof(vis) );



    for ( int i = 1; i < 10; ++i )

    {

        if ( !ok[i] ) continue;

        int hashh = i % N;

        if ( vis[hashh] ) continue;

        vis[hashh] = true;

        Q[tail] = node( hashh, -1, i );

        if ( hashh == 0 ) return tail;

        ++tail;

    }



    while ( head < tail )

    {

        node cur = Q[head];

        for ( int i = 0; i < 10; ++i )

        {

            if ( !ok[i] ) continue;

            int hashh = ( cur.mod * 10 + i ) % N;



            if ( vis[hashh] ) continue;

            vis[hashh] = true;

            Q[tail] = node( hashh, head, i );

            if ( hashh == 0 ) return tail;

            ++tail;

        }

        ++head;

    }

    return -1;

}



int main()

{

    int cas = 0;

    while ( scanf( "%d", &N ) == 1 )

    {

        memset( ok, true, sizeof(ok) );

        int n;

        scanf( "%d", &n );

        for ( int i = 0; i < n; ++i )

        {

            int digit;

            scanf( "%d", &digit );

            ok[digit] = false;

        }



        printf( "Case %d: ", ++cas );

        int ans = BFS();

        if ( ans != -1 ) findFa( ans );

        else printf("-1");



        puts("");

    }

    return 0;

}

 

你可能感兴趣的:(HDU)