POJ 1006 中国余数定理
2016-03-05 20:05
267 查看
这里题考查的 并不是 编程题,严格来说, 是一道数学题。
主要考察中国余数定理。
这里举一个典型的例子,就是,n % 3 = 2, n % 5 = 3, n % 7 = 2; 问n是多少?
这道题枚举当然可以算出来,但是运用定理可以将复杂度降到O(1),它是怎么做到的呢?
首先,我们求出5*7的倍数,并且它除以3余1; 同理,求出3*7的倍数,并且它除以5余1; 同理,求出3*5的倍数,并且它除以7余1.
然后我们将求出的三个数,暂且称为a,b,c . 做一个简单的运算,也就是求和sum = 2*a + 3*b + 2*c
最后,求出3,5,7的最小公倍数lcm(3,5,7) .那么结果也就是result = sum % lcm
那么回到这个题目,我们可以列出这样的等式:
(n+d)%23 = p
(n+d)%28 = e
(n+d)%33 = i
题目也就是要我们求n, 这里我们可以求得 sum = p*5544 + e*14421 + i*1288
这里的5544,14421,1288怎么得来,当然可以借助for循环,当满足条件时将倍数输出,即可,这里的倍数分别是6,19,2
所以,最后的结果是 result = (sum - d + 21252)%lcm(23,28,33)
这里为什么要将 -d 放在括号里面,因为防止这样的情况,结果应该为21252,放在外面会变成0. 例子:19 0 1 364
这里注意的是,括号里面加了一个21252,这样是为了防止 出现负数
#include<iostream>
using namespace std;
int main(){
int p,e,i,d;
int count=1;
int lcm = 23*28*33;
int days;
while(cin>>p>>e>>i>>d){
if(p==-1&&e==-1&&i==-1&&d==-1)
break;
days = (5544*p+14421*e+1288*i-d)%lcm;
days = (days+21252)%21252; //防止产生负数
if(days == 0)
days = 21252;
cout<<"Case "<<count<<": the next triple peak occurs in "<<days<<" days."<<endl;
count++;
}
return 0;
}
主要考察中国余数定理。
这里举一个典型的例子,就是,n % 3 = 2, n % 5 = 3, n % 7 = 2; 问n是多少?
这道题枚举当然可以算出来,但是运用定理可以将复杂度降到O(1),它是怎么做到的呢?
首先,我们求出5*7的倍数,并且它除以3余1; 同理,求出3*7的倍数,并且它除以5余1; 同理,求出3*5的倍数,并且它除以7余1.
然后我们将求出的三个数,暂且称为a,b,c . 做一个简单的运算,也就是求和sum = 2*a + 3*b + 2*c
最后,求出3,5,7的最小公倍数lcm(3,5,7) .那么结果也就是result = sum % lcm
那么回到这个题目,我们可以列出这样的等式:
(n+d)%23 = p
(n+d)%28 = e
(n+d)%33 = i
题目也就是要我们求n, 这里我们可以求得 sum = p*5544 + e*14421 + i*1288
这里的5544,14421,1288怎么得来,当然可以借助for循环,当满足条件时将倍数输出,即可,这里的倍数分别是6,19,2
所以,最后的结果是 result = (sum - d + 21252)%lcm(23,28,33)
这里为什么要将 -d 放在括号里面,因为防止这样的情况,结果应该为21252,放在外面会变成0. 例子:19 0 1 364
这里注意的是,括号里面加了一个21252,这样是为了防止 出现负数
#include<iostream>
using namespace std;
int main(){
int p,e,i,d;
int count=1;
int lcm = 23*28*33;
int days;
while(cin>>p>>e>>i>>d){
if(p==-1&&e==-1&&i==-1&&d==-1)
break;
days = (5544*p+14421*e+1288*i-d)%lcm;
days = (days+21252)%21252; //防止产生负数
if(days == 0)
days = 21252;
cout<<"Case "<<count<<": the next triple peak occurs in "<<days<<" days."<<endl;
count++;
}
return 0;
}
相关文章推荐
- C++ Builder string相互转换
- 使用MR求解多个矩阵的乘积之后
- Java笔记
- windows cmd 下 显示文件列表 并导入文件
- 12 完整的圆的绘制-DirectX游戏开发初级教程
- 文件保存和读取
- java(二十三) 可变类和不可变类
- windows批处理命令教程
- 有k个list列表, 各个list列表的元素是有序的,将这k个列表元素进行排序( 基于堆排序的K路归并排序)
- shell脚本自动化打包构建_project和workspace打包的区别
- os和os.path模块
- Linux-find和grep命令
- os和os.path模块
- Java开发者对于Java所要关注的几个点
- UESTC oj 谕神的密码
- 十道海量数据面试题
- Linux内核分析作业 NO.2
- OSI参考模型
- 排序之快速排序
- json排序