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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章