编程之美——读书心得 2.8找符合条件的整数
来源:互联网 发布:快速排序java 编辑:程序博客网 时间:2024/05/16 11:44
问题:任意给定一个正整数,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0。
看了题目要求之后,我们的第一想法就是从小到大枚举M的取值,然后再计算N * M,最后判断它们的乘积是否只含有1和0。大体的思路可以用下面的伪代码来实现:
for(M = 2; ; M++)
{
product = N * M;
if(HasOnlyOneAndZero(product))
output N, M, Product, and return;
}
但是问题很快就出现了,什么时候应该终止循环呢?这个循环会终止吗?即使能够终止,也许这个循环仍需要耗费太多的时间,比如N = 99时,M = 1 122 334 455 667 789,N * M = 111 111 111 111 111 111。
分析从这里开始:
我们要求得M,首先要证明M存在。
一、证明:M一定存在,而且不唯一。
100%N,101%N,102%N,...,10x%N....这是一个无穷数列,且数列中每一项取值范围都在[0,N-1]之。所以这个无穷数中间必定才能在循环节假设 s,t 均为正整数,且s<t ,
10s%N = 10t%N 则 10t-s%N = 1 , t-s是N的循环节
(之前在哪看到的,我忘记了,不好意思。这里不是很懂)
二、求解M。
问题转换,由最初的暴力求解M使得N*M的乘积有1和0转换为===>求解最小的正整数X,使得X的十进制表示只有1和0,并且X被N整除。
X的取值:1,,1,11,100,101,110,111,1000,……
若X最终位为K位,则要循环搜索2^k次,所以寻找最小的X,使得X mod N ==0即可。
我插入一些关于取模定律的知识:
同余式:a,b对p取模,它们余数相同,记做 a ≡ b (mod p)
定律:若a≡b (% p),则对于任意的c,都有(a + c) ≡ (b + c) (%p);
若a≡b (% p),则对于任意的c,都有(a * c) ≡ (b * c) (%p);
应用到这里,
∵1%3=1, 10%3=1;
∴1≡10%3
所以,(1+100)%3≡(10+100)%3,即101%3≡110%3
所以,可以只计算同位数小的数值即可。x,10x,10x+1 同余
例如,1001与1010
设 X=10^k, 10^k %N =a
那么X为K+1 位时, X = 10^k +Y (0<Y<10^k)
对Y搜索,将有2^k-1个数据。
那么可以这样处理(思想):把Y按照对N的余数分解,将搜索空间分成N-1个子空间。对于每一个子空间,只需判断其中最小元素加上10^k能否被N整除即可。
这样,搜索空间从2^k-1压缩至N-1维。(前提是前面的计算已保留了余数信息,并且把Y的搜索空间进行了分解,即X%N的各种可能)
然后,10^k与Y的取模结果想加,再%N,看是否有新余数产生。这一步需要循环N次,因为已经将Y分成了N租。那么总的部署为(K-1)*N步。(从根至叶子自顶向下,深度搜索余数信息的次数)
// 将搜索空间分过类的广度搜索,这样空间占用是O(N)而不是// 指数级。分类的原则是按照模N的余数分类 #define _CRT_SECURE_NO_WARNINGS 1#include <cstdio>#include <bitset>#include <vector>#include <queue>using namespace std;struct QNode {int v, r; // v is value, r is remainderQNode(int vv, int rr): v(vv), r(rr) {}QNode(): v(0), r(0) {}};int main() {int N;while(scanf("%d", &N) != EOF) {//bitset<N> bn;queue<QNode> q;q.push(QNode(1, 1));while(!q.empty()) {//bn.reset();vector<bool> bn(N, false);int s = q.size();while(s--) {QNode t = q.front();if(t.r == 0) {printf("n = %d, m = %d, n*m = %d/n", N, t.v/N, t.v);goto ok;}q.pop();if(!bn[t.r * 10 % N]) { //注意这里bn[t.r * 10 % N] = true;q.push(QNode(t.v * 10, t.r * 10 % N));}if(!bn[(t.r * 10 + 1) % N]) {bn[(t.r * 10 + 1) % N] = true;q.push(QNode(t.v * 10 + 1, (t.r * 10 + 1) % N));}}}ok:;}return 0;}
参考信息:http://blog.csdn.net/jcwKyl/article/details/3859155
- 编程之美——读书心得 2.8找符合条件的整数
- 编程之美——找符合条件的整数
- 编程之美——找符合条件的整数
- 编程之美——找符合条件的整数
- 编程之美——找符合条件的整数
- 编程之美——找符合条件的整数
- 编程之美2.8 找符合条件的整数
- 【编程之美2.8】找符合条件的整数
- 编程之美2.8找符合条件的整数
- 编程之美2.8 找符合条件的整数
- 编程之美2.8 找符合条件的整数
- 编程之美2.8找符合条件的整数
- 编程之美2.8 找符合条件的整数
- 编程之美——2.8 找符合条件的整数
- 编程之美2.8——找符合条件的整数
- 编程之美读书笔记2.8—找符合条件的整数
- 编程之美-找符合条件的整数
- 编程之美-找符合条件的整数
- ios应用程序多语言,根据系统语言
- iOS开发之获取手机通讯录联系人信息<一>
- 转:融资4800万美金,艾维邑动凭什么?
- freopen()函数
- 深入理解递归算法
- 编程之美——读书心得 2.8找符合条件的整数
- PAT(Basic Level) 1022 D进制的A+B (20)
- Layered connections through a proxy server
- Eclipse IDE 常用快捷键
- C# Redmine Rest API使用经验
- C#对Excel操作
- 滕王阁序
- C# 判断两张图片是否一致,极快速。
- Java修改文件名