poj1465

Multiple
Time Limit: 1000MS Memory Limit: 32768K
Total Submissions: 5423 Accepted: 1179

Description

a program that, given a natural number N between 0 and 4999 (inclusively), and M distinct decimal digits X1,X2..XM (at least one), finds the smallest strictly positive multiple of N that has no other digits besides X1,X2..XM (if such a multiple exists).

Input

The input has several data sets separated by an empty line, each data set having the following format:

On the first line - the number N
On the second line - the number M
On the following M lines - the digits X1,X2..XM.

Output

For each data set, the program should write to standard output on a single line the multiple, if such a multiple exists, and 0 otherwise.

An example of input and output:

Sample Input

22
3
7
0
1

2
1
1

Sample Output

110
0
 
     一道比較經典的BFS,剪紙策略真的很強大,值得學習!!
剪枝策略:
若A=n*i+r
  B=n*j+r
即A和B同餘(i<j),那麼若A*10+d[k]能被n整除,那麼B*10+d[k]也能被n整除(其中d[k]表示允許出現的一個數字),所以此處就可以做個剪枝了,對於餘數相同的數取其最小的。
 
ps:由於最後的結果可能會很大,所以我在每個狀態節點中記錄了前一個狀態,而且在每個狀態中記錄當前狀態是由哪個數字得到的。
#include<iostream>
#include<algorithm>
#include<cstdio>

using namespace std;
struct st
{
    int pre;//前一個狀態
    int r;//餘數
    int d;//個位數
}w,v;
st q[5000];
int num[10];//數字
bool visit[5000];
int n,m;

void output(int i)
{
    if(q[i].pre==-1)
        return;
    output(q[i].pre);
    printf("%d",q[i].d);
}

void bfs()
{
    if(n==0)
    {
        printf("0\n");
        return;
    }
    int front,rear;
    bool ok;
    front=rear=0;
    w.pre=-1;
    w.d=0;
    w.r=0;
    q[rear++]=w;
    visit[0]=true;
    ok=false;
    while(front<rear)
    {
        w=q[front++];
        for(int i=0;i<m;i++)
        {
            int r=w.r*10+num[i];
            if(r>=n&&r%n==0)
            {
                output(front-1);
                printf("%d\n",num[i]);
                ok=true;
                break;
            }
            r%=n;
            if(!visit[r])
            {
                visit[r]=true;
                v.r=r;
                v.pre=front-1;
                v.d=num[i];
                q[rear++]=v;
            }
        }
        if(ok)
            break;
    }
    if(!ok)
        printf("0\n");
}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=0;i<n;i++)
            visit[i]=false;
        for(int i=0;i<m;i++)
            scanf("%d",num+i);
        sort(num,num+m);//由小到大排序
        bfs();
    }
    return 0;
}

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