hdu 1664 Different Digits 数位BFS(怎么都是这些题……

Description

Given a positive integer n, your task is to find a positive integer m, which is a multiple of n, and that m contains the least number of different digits when represented in decimal. For example, number 1334 contains three different digits 1, 3 and 4.

Input

The input consists of no more than 50 test cases. Each test case has only one line, which contains a positive integer n ( 1<=n < 65536). There are no blank lines between cases. A line with a single `0' terminates the input.

Output

For each test case, you should output one line, which contains m. If there are several possible results, you should output the smallest one. Do not output blank lines between cases.

Sample Input

7 
15 
16 
101 
0

Sample Output

7
555
16
1111

稍微有点不一样    这次衡量的第一标准是位数的多少    第二标准才是数的大小

这里必须有一个    数论的   知识   不然不好写(I hate number theroy ......

对于任意的整数n,必然存在一个由不多于两个的数来组成的一个倍数。(之前写过数位BFS的应该可以理解

因为a,aa,aaa……取n+1个,则必有两个模n余数相同,相减即得n的倍数m。而m只由a、0组成。(这可以说是最糟的情况

所以只要先枚举所有的  1-9  的数   如果不存在   再枚举两个数的情况   (一直很奇怪网上的题解   0-9 不是有  45种情况么…………

还有   。。。沃特么也是SB  被自己坑到了    我还以为必须是他给的数  的位数作为范围   因为样例就是这样的……  结果WA了好几发


ac code

#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <string>

using namespace std;
const int maxn=65540;
const int inf=0x3f3f3f3f;
int n,k,num[11],a[5];
char ch[3];
bool vis[maxn],flag[11];
string curans,ans;

struct node
{
    char ch;
    int pre,mod;
}que[maxn*10];

void getstr(int x)
{
    if(que[x].pre!=-1)
        getstr(que[x].pre);
    curans+=que[x].ch;
}

bool bfs(int kk)
{
    memset(vis,false,sizeof vis);
    int l=1,r=1;
    for(int i=0;i<kk;i++) if(a[i])
    {
        que[r].pre=-1;
        vis[que[r].mod=a[i]%n]=true;
        que[r].ch=a[i]+'0';
        r++;
    }
    while(l<r)
    {
        for(int i=0;i<kk;i++)
        {
            int tmp=que[r].mod=(que[l].mod*10+a[i])%n;
            if(!vis[tmp])
            {
                vis[tmp]=true;
                que[r].pre=l;
                que[r].ch=a[i]+'0';
                if(tmp==0)
                {
                    getstr(r);
                    return true;
                }
                r++;
            }
        }
        l++;
    }
    return false;
}

bool cmp(const string& a,const string &b)
{
    if(a.size()==b.size()) return a<b;
    return a.size()<b.size();
}

int main()
{
    while(scanf("%d",&n),n)
    {
        if(n<=11)//11之前直接输出    可以减少bfs的判断
        {
            printf("%d\n",n);
            continue;
        }
        ans="";
        bool wokao=false;
        for(int i=1;i<10;i++)
        {
            a[0]=i;
            curans="";
            if(bfs(1))
                if(!wokao||cmp(curans,ans))//大小关系是未知的   必须加以判断
                {
                    wokao=true;
                    ans=curans;
                }
        }
        if(wokao)
            cout<<ans<<endl;
        else
        {
            for(int i=0;i<10;i++)
                for(int j=i+1;j<10;j++)
                {
                    a[0]=i,a[1]=j;
                    curans="";
                    if(bfs(2))
                        if(!wokao||cmp(curans,ans))
                        {
                            wokao=true;
                            ans=curans;
                        }
                }
            cout<<ans<<endl;
        }
    }
    return 0;
}

//写多了就没啥好说的了








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值