hdu 4474 Yet Another Multiple Problem 模型转换 BFS搜索 根据剩余类建图广搜

题意:

  给一个N(n<=1e4), M个数字(长度为1),问最小的数x(x%n=0) 不包含这m个数。

思路:

  直接求,没想出解法.

  对于一个数 x%n = m, 则 x` = x*10+i  , 有 m` = (m*10+i)%n

  我们可以利用 除了M个数字外的 数来构造这个 X. 

  因为需要最小的, 则其长度与字典序排列皆最小. 通过BFS进行搜索. 每一个 模n的余数之取第一次出现的,

因为之后再出现的. 只可能更长或者更大. 必定不是最优解.

  搜索节点,保存三个信息:  当前x的最后一位, 当前x%n的余数, 当前节点的父亲节点. 

  结果输出利用记忆父亲节点 ,然后递归输出即可.

View Code
#include<cstdio>

#include<cstring>

#include<cstdlib>



const int N = (int)1e4+10;



struct node{

    int m, f;

    char c;

}Q[N], tmp;



bool vis[N],legal[10];

int n, m;



void print(int k){

    //if( k == -1 ) return;

    if( Q[k].f != -1 ) print(Q[k].f);

    printf("%c", Q[k].c );

}

int main(){

    int Case = 1;    

    while( scanf("%d%d",&n,&m) != EOF){

        memset( vis, 0, sizeof(vis));

        memset( legal, 0, sizeof(legal));

        for(int x, i = 0; i < m; i++){

            scanf("%d",&x);

            legal[x] = 1;    

        }    

        int l = 0, r = 0, res = -1;

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

            if( !legal[i] ){

                tmp.c = i+'0'; tmp.m = i%n; tmp.f = -1;

            //    if( !vis[tmp.m] ){

                    vis[tmp.m] = 1;

                    Q[r++] = tmp;    

                    if( tmp.m == 0 ){

                        res = r-1; break;    

                    }    

        //        }

            }    

        } 

        while( (l < r) && (res==-1) ){

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

                tmp.m = (Q[l].m*10+i)%n; tmp.c = i+'0'; tmp.f = l;    

                if( !legal[i] && !vis[tmp.m] ){

                    vis[tmp.m] = 1;

                    Q[r++] = tmp;    

                    if( tmp.m == 0 ){

                        res = r-1; break;    

                    }    

                }

            }

            l++;    

        }    

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

        if( res == -1 ) printf("-1\n");

        else    {print(res);puts("");}

    }    

    return 0;

}

 

你可能感兴趣的:(HDU)