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

poj1465

2013年07月20日 ⁄ 综合 ⁄ 共 1641字 ⁄ 字号 评论关闭
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;
}

抱歉!评论已关闭.