SPOJ 370 SPOJ ONEZERO(BFS + 递归)

ONEZERO - Ones and zeros

 

Certain positive integers have their decimal representation consisting only of ones and zeros, and having at least one digit one, e.g. 101. If a positive integer does not have such a property, one can try to multiply it by some positive integer to find out whether the product has this property.

Input

Number K of test cases (K is approximately 1000);
in each of the next K lines there is one integer n (1 <= n <= 20000)

Output

For each test case, your program should compute the smallest multiple of the number n consisting only of digits 1 and 0 (beginning with 1).

ExampleInput:3111011

17
Output:
11101
11011
11101


  题意:给定一个两万以内的数,如果这个数是只由0和1组成的,则直接输出;
如果不是只由0和1组成的,则找到这个的的倍数中最小的一个只由0和1组成的数,输出。
  思路:这个题相对来说思路有点难想,看了好久的对的代码(http://blog.csdn.net/primoblog/article/details/9819823)
才弄明白了什么意思,然后自己实践了一遍。说说我的思路:每一次都进行对余数进行标记,对于一个只含有0和1的数,首位一定是只能是1,然后每一次都进行在这个数的后面
添加一个数,判断这个数除以输入的数的余数,如果说这个余数已经被计算过,那么没有必要再进行判断,一定不会满足,如果说这个余数为0的话,得到的这个数一定是该数最小的倍数。
输出的时候进行递归输出,注意递归的出口。

#include <algorithm>
#include <string.h>
#include <stdio.h>
#include <queue>
 
const int MAX = 20010;
 
using namespace std;
 
int vis[MAX], t, n, k;
struct data
{
    int x;     //记录得到下一步的时候这个数是多少
    bool flag; //记录此时添加的数是多少
}a[MAX];
 
//判断这个数是不是只由0和1组成
bool judge(int n)
{
    while(n)
    {
        int num = n % 10;
        n /= 10;
        if(num != 0 && num != 1)
            return 0;
    }
    return 1;
}
 
void print(int x)
{
    // 递归的出口
    if(x < 0)
        return;
 
    print(a[x].x);
 
    printf("%d", a[x].flag);
    //此时递归完毕,输出换行终止
    if(x == 0)
        printf("\n");
}
 
void BFS()
{
    //把所要找的数的第一个数放进去,一定为1
    vis[1] = 1;
    a[1].x = -1;
    a[1].flag = 1;
 
    queue<int> que;
    que.push(1);
 
    while(!que.empty())
    {
        k = que.front();
        que.pop();
 
        //如果此余数没有被用到,则进行判断
        if(vis[k * 10 % n] == 0)
        {
            int sum = k * 10 % n;
            //记录上一个数
            a[sum].x = k;
            //记录此时在结尾添加的数
            a[sum].flag = 0;
 
            if(sum == 0)//余数为0,说明已经找到
                break;
             
            //标记这个余数
            vis[sum] = 1;
            que.push(sum);
        }
 
        if(vis[(k * 10 + 1) % n] == 0)
        {
            int sum = (k * 10 + 1) % n;
            a[sum].x = k;
            a[sum].flag = 1;
 
            if(sum == 0)
                break;
 
            vis[sum] = 1;
            que.push(sum);
        }
    }
    print(0);
}
 
int main()
{
    scanf("%d", &t);
    while(t --)
    {
        memset(vis, 0, sizeof(vis));
        scanf("%d", &n);
        if(judge(n))
        {
            printf("%d\n", n);
            continue;
        }
        BFS();
    }
    return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值