POJ1426 建议打表做该题/用数组模拟队列(比STL队列速度要快)
2016-05-18 21:21
435 查看
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)
简单深搜,及时回溯防止溢出,在不知道上限的情况下,也是水过
2)
广搜+long long,C++会报超时(g++AC)(但是用数组模拟queue就可以过如下面③,于是是不是佐证了STL比数组的效率低呢)
广搜+string,因为同样用了STL的队列,C++下超时
3)这个就是用数组模拟了STL中的queue了,仅仅学习代码中如何用数组模拟队列进行bfs广搜即可,因为mod的大小不容易确定,所以这种做法我认为不适合这道题。(我还是觉得打表比较适合这道题...)
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
Sample Output
题意:
求一个数的(任意一个)倍数,并且这个倍数仅由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 =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
相关文章推荐
- Yii2.0 自定义日志类
- Libgdx之Label Image
- 面向项目(十一)—— 库的使用
- JAVA-007前面所学总结加深
- 第十三周的学习进度表
- IOI2000 邮局
- iOS蓝牙开发(一)蓝牙相关基础知识
- 渣渣的艰难的找实习经历
- 5月17日 AJAX 之 XML
- ab中文手册
- AngularJS之表单验证
- 快速排序算法(排序详解)
- sdut oj 2404 super prime(素数筛)
- 删除vi编辑产生的.swp文件
- 快速排序
- jquery语法
- 架构大数据分析应用
- JAXB - Validate Document before It is Unmarshalled
- Long Short-Term Memory (LSTM)公式简介
- addEventListener和removeEventListener