poj1465

来源:互联网 发布:es6数组去重 编辑:程序博客网 时间:2024/05/18 02:43
Multiple
Time Limit: 1000MSMemory Limit: 32768KTotal Submissions: 5423Accepted: 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

223701211

Sample Output

1100
 
     一道比较经典的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;}

原创粉丝点击