现在的位置: 首页 > 综合 > 正文

poj 1465

2013年05月25日 ⁄ 综合 ⁄ 共 1405字 ⁄ 字号 评论关闭

  题意是: 给出一个 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;
}

抱歉!评论已关闭.