poj 1465 Multiple

http://poj.org/problem?id=1465

题目大意:

给你一个n 再给你m 个一位整数  问用这m个数

可以组合出最小的n的倍数  没有则输出 0

bfs + 余数剪枝    相同余数不能出现两次

m个数需要排序 才能保证最小

中间可能出现大整数 要处理

代码及其注释:

#include<iostream>

#include<cstdio>

#include<cstdlib>

#include<ctime>

#include<queue>

#include<cstring>

#include<set>

#include<string>

#include<cmath>

#include<algorithm>

#define LL long long



using namespace std;



const int N=1005;

bool had[N*5];//标记是否此余数是否出现过

string a[12];

queue<string>str;//防止大整数情况

int MOD(string s,int n)//求余数

{

    int k=0;

    for(int i=0;i<s.size();++i)

    {

        k=(k*10+s[i]-'0')%n;

    }

    return k;

}

int main()

{

    //freopen("data.txt","r",stdin);

    int n,m;

    while(cin>>n>>m)

    {

        while(!str.empty())

        str.pop();

        memset(had,false,sizeof(had));

        for(int i=0;i<m;++i)

        {

            cin>>a[i];

        }

        if(n==0)//0 要特判

        {

            printf("0\n");

            continue;

        }

        sort(a,a+m);//排序

        string ans="0";

        int i;

        for(i=0;i<m;++i)

        {

            if(a[i]!="0")

            {

                int l=MOD(a[i],n);

                if(l==0)//余数为0 的话直接跳出循环

                {

                    ans=a[i];

                    break;

                }

                if(!had[l])//去重

                {

                    had[l]=true;

                    str.push(a[i]);

                }

            }

        }

        if(i>=m)//需要继续广搜

        while(!str.empty())

        {

            string x=str.front();//cout<<x<<endl;

            str.pop();

            int j;

            for(j=0;j<m;++j)

            {

                string k=x+a[j];

                int l=MOD(k,n);

                if(had[l]==false)//余数不能重

                {

                    had[l]=true;

                    if(l==0)//发现合适的 知道跳出循环

                    {

                        ans=k;

                        break;

                    }

                    str.push(k);

                }

            }

            if(j<m)

            break;

        }//cout<<endl;

        cout<<ans<<endl;

    }

    return 0;

}

  

你可能感兴趣的:(poj)