poj 1465

  题意是: 给出一个 0 - 4999 的数 N  ,在给出 M 个0-9的数,判断这M个数字能不能构成一个数是N的倍数,如果有输出最小的,如果没有输出0。

此题用BFS 。。 这个题好在 用 余数判重剪枝。。 

 

BFS  如果不加以剪枝,一定会搜索的情况会很庞大。所以应该用余数判重 。

   为什么可以用余数判重?

       A=a*N +e 即A%N =e

       B= b*N+e即B%N=e

      当A  B mod N的余数相同时,如果先出现A 。

      在A  后加上一个数 i 时 ,  新的数   C = 10 *a*N + 10 *e+i;

      同样  B后加上数 i 时 , D = 10*b*N +10*e+i;    由于C D 前边 10*a*N 和 10*b*N 都是N的倍数 ,则C D mod N 的余数都是有 10*e+i 决定的。

    于是 C D  mod N 同余。

    因此 A B 同余 都添加上 i 之后 新的两个数C D也是同余的。在无论添加多少个数,新生成的两个数也是同余的。因此 在A 之后如果不出现 N的倍数 ,则

在B之后也不会出现。 在A 之后出现,那B之后也会出现。  有因为要求求最小值。所以只需要搜索min(A,B)之后的 ,对于另外一个数之后就不用搜索了。

#include<cstdlib>

#include<iostream>

#include<cstdio>

#include<cmath>

#include<cstring>

#include<algorithm>

#include<set>

#include<map>

#include<list>

#include<queue>

#include<vector>

#define LL long long

#define inf 0x7fffffff

#define eps 1e-7

#define N 5509

#define M 20009

using namespace std;

int T,n,m,k;

struct Node

{

    LL v;

    int w;

    int pre;

} a[N];

int h[100];

int vis[N];

void print(int x)

{

    if(x)

    {

        print(a[x].pre);

        printf("%d",a[x].w);

    }

}

void bfs()

{

    int l=0,r=1;

    a[0].pre=a[0].w=a[0].v=0;

    while(l<r)

    {

        Node t;

        t=a[l];

        t.pre=l++;

        int v=t.v;

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

        {

            int x=(v*10+h[i])%n;//n不能是0,Float-Point Error

            if(x==0&&l!=1)

            {

                print(t.pre);

                printf("%d\n",h[i]);

                return ;

            }

            if(vis[x]||(l==1&&h[i]==0))continue;

            vis[x]=1;

            t.v=x;

            t.w=h[i];

            a[r++]=t;

        }

    }

    printf("0\n");

}

int main()

{

#ifndef ONLINE_JUDGE

    freopen("ex.in","r",stdin);

#endif

    int ncase=0;

    while (scanf("%d%d",&n,&m)==2)

    {

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

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

        {

            scanf("%d",&h[i]);

        }

        if (n==0)//

        {

            printf("0\n");

            continue;

        }

        sort(h,h+m);

        bfs();

    }

    return 0;

}



你可能感兴趣的:(poj)