POJ1426 建议打表做该题/用数组模拟队列(比STL队列速度要快)


0)

题意:

         求一个数的(任意一个)倍数,并且这个倍数仅由0和1组成。


分析:

       深搜所有0、1组成的数,直到出现所求数的倍数。

      ①题目中说 The decimal representation of m must not contain more than 100 digits.看起来很吓人,结果证明只算long long int的最大范围内(10^19之内)的由0、1组成的数就可以AC。当然,bfs或者dfs都可以,不过bfs要自己写数组模拟queue,否则会超时(C++下),而dfs注意及时回溯(以防止数大于Longlong),可以再用同余模定理做一下优化或者不做优化。

       ②其中。对于数组模拟队列的bfs,用一个数组存储出现的余数,然后用该数组以及下标/2来模拟bfs队列,用下标%2==0或者==1来代表在这一层所得到的数后面+0还是+1。问题是,那么从1、10、11、 100、 101、 110、 111...直到出现该数的由0、1组成的倍数,中间最多要经过多少余数的存储呢,虽然后来证明是524286,但事先恐怕不好预算,得先打表看看哪个余数最长,但为了余数的上限而去打表太麻烦了,还不如高精度+队列直接线下把答案打表,所以贴③的代码,只是学习一下用数组和下标%2,来模拟bfs双入口即可。

       ③因为n是1到200,所以最后还是推荐直接用大数的高精度除法和bfs来对答案进行打表;也可以直接将答案输到数组,然后粘到程序里查询AC...;当然,如果发现最长的数不超过20位,那就也可以用深搜或广搜+long long 过。

   

1)

简单深搜,及时回溯防止溢出,在不知道上限的情况下,也是水过

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
bool found;
void DFS(unsigned __int64 t ,int n,int k)
{
    if(found)
        return ;//如果已经发现了答案就没搜的必要了
    if(t%n==0)
    {//发现答案,输出,标记变量该true
        printf("%I64u\n",t);
        found=true;
        return ;
    }
    if(k==19)//到第19层,回溯(以防止数大于10^19就超过了long long 范围了)
        return ;
    DFS(t*10,n,k+1);    //搜索×10
    DFS(t*10+1,n,k+1);    //搜索×10+1
}
int main()
{
    int n;
    while(cin>>n,n)
    {
        found=false;//标记变量,当为true代表搜到了题意第一的m
        DFS(1,n,0);    //从1开始搜n的倍数,第三个参数代表搜的层数,当到第19层时返回(因为第20层64位整数存不下)
    }
    return 0;
}


2)

广搜+long long,C++会报超时(g++AC)(但是用数组模拟queue就可以过如下面③,于是是不是佐证了STL比数组的效率低呢)

#include<iostream>
#include<stdio.h>
#include<queue>
using namespace std;
void bfs(int n)
{
    queue<long long>q;
    q.push(1);
    while(!q.empty())
    {
        int i;
        long long x;
        x=q.front();
        q.pop();
        if(x%n==0)
        {
            printf("%lld\n",x);
            return ;
        }
        q.push(x*10);
        q.push(x*10+1);
    }
}
int main()
{
    int n;
    while(scanf("%d",&n)&&n)
    {
        bfs(n);
    }
    return 0;
}


广搜+string,因为同样用了STL的队列,C++下超时

#include<iostream>
#include<string>
#include<iomanip>
#include<algorithm>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <queue>
using namespace std;

struct Node{
	int mod;
	string ans;
}node,nn[210];
void bfs(int n){
	queue <Node> q; //
	struct Node now;
	now.mod=1%n;
	now.ans="1";
	q.push(now);
	while(!q.empty()){
		now=q.front();
		q.pop();
		if(now.mod%n==0){
			nn[n]=now;
			return ;
		}
		struct Node next1;
		struct Node next2;
		next1.mod=(now.mod*10)%n;
		next1.ans=now.ans+"0";
		q.push(next1);

		next2.mod=(now.mod*10+1)%n;
		next2.ans=now.ans+"1";
		q.push(next2);
	}

}
int main()
{
	int k;
	nn[1].ans="1";
	for(int i=2;i<=200;i++){
		if(i%2==0){
			nn[i].ans=nn[i/2].ans+"0";
		}
		else
			bfs(i);
	}
	while(cin>>k&&k!=0){
		cout<<nn[k].ans<<endl;
    }

}



3)这个就是用数组模拟了STL中的queue了,仅仅学习代码中如何用数组模拟队列进行bfs广搜即可,因为mod的大小不容易确定,所以这种做法我认为不适合这道题。(我还是觉得打表比较适合这道题...)

//Memory Time
//2236K  32MS 

#include<iostream>
using namespace std;

int mod[524286];  //保存每次mod n的余数
                  //由于198的余数序列是最长的
                  //436905是能存储198余数序列的最少空间
                  //但POJ肯定又越界测试了...524286是AC的最低下限,不然铁定RE

int main(int i)
{
	int n;
	while(cin>>n)
	{
		if(!n)
			break;

		mod[1]=1%n;  //初始化,n倍数的最高位必是1

		for(i=2;mod[i-1]!=0;i++)  //利用同余模定理,从前一步的余数mod[i/2]得到下一步的余数mod[i]
			mod[i]=(mod[i/2]*10+i%2)%n;
		             //mod[i/2]*10+i%2模拟了BFS的双入口搜索
		             //当i为偶数时,+0,即取当前位数字为0  。为奇数时,则+1,即取当前位数字为1

		i--;
		int pm=0;
		while(i)
		{
			mod[pm++]=i%2;   //把*10操作转化为%2操作,逆向求倍数的每一位数字
			i/=2;
		}
		while(pm)
			cout<<mod[--pm];  //倒序输出
		cout<<endl;
	}
	return 0;
}


4)

Description

Given a positive integer n, write a program to find out a nonzero multiple m of n whose decimal representation contains only the digits 0 and 1. You may assume that n is not greater than 200 and there is a corresponding m containing no more than 100 decimal digits.

Input

The input file may contain multiple test cases. Each line contains a value of n (1 <= n <= 200). A line containing a zero terminates the input.

Output

For each value of n in the input print a line containing the corresponding value of m. The decimal representation of m must not contain more than 100 digits. If there are multiple solutions for a given value of n, any one of them is acceptable.

Sample Input

2
6
19
0

Sample Output

10
100100100100100100
111111111111111111



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值