51nod 1109 01组成的N的倍数

基准时间限制:1 秒 空间限制:131072 KB 分值: 40  难度:4级算法题
给定一个自然数N,找出一个M,使得M > 0且M是N的倍数,并且M的10进制表示只包含0或1。求最小的M。
例如:N = 4,M = 100。
Input
输入1个数N。(1 <= N <= 10^6)
Output
输出符合条件的最小的M。
Input示例
4
Output示例
100

解题思路:运用队列存储余数,逐一判断,知道满足条件,每次在M后面添加一位数a(题目要求其中a为0或者为1),使M扩大为10*M+a

即:原数为M,扩大后的数为M1=10*M+a

        将其对mod取模,则:mod_M=M%mod    mod_M1=(10*M+a)%mod = (10*M%mod + a%mod)%mod =  (10*M%mod+a)%mod = (10*mod_M+a)%mod

        由此我们可以知道,当M满足条件时,则:mod_M1=0

       可以将其假设成为一个带权值的图,其权值为数字0或者1,其顶点值为余数,最后可以看成从起点到第一个顶点为0的路径就是最后结果;

       在余数入队的时候要判断是否在之前就出现过,如果出现过,则不入队,因为如果出现重复的,那么就会出现无限循环,这样永远也得不到余数为0 的这个条件,所以直接舍去,如果没有出现过,则将其入队,并且用b数组将其标记,a数组用来保存权值,其中两者都以余数作为下标;则b数组保存路径,a数组保存权值,最后根据路径输出所以权值。

         

代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;
int a[maxn],b[maxn];
void print(int s)///输出函数
{
    if(s==-1) return ;
    print(b[s]);
    printf("%d",a[s]);
}
int main()
{
    int n,f=0,s;
    scanf("%d",&n);
    if(n==1) {printf("1\n"); return 0;}///1作为特判
    queue<int>Q;
    Q.push(1);
    b[1] = -1;
    a[1] = 1;
    while(!Q.empty())
    {
        s=Q.front();
        Q.pop();
        int c1=10*s%n,c2=(10*s+1)%n;
        if(c1 == 0) {f=0; break;}
        if(c2 == 0) {f=1; break;}
        if(!b[c1]){Q.push(c1); a[c1] = 0; b[c1]=s;}///判断是否出现循环
        if(!b[c2]){Q.push(c2); a[c2] = 1; b[c2]=s;}
    }
    print(s);
    printf("%d\n",f);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值