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;
}
原文地址:https://www.cnblogs.com/GBRgbr/p/3360143.html