POJ 2635 The Embarrassed Cryptographer尴尬的译解密码者
2015-06-09 22:53
387 查看
2015年5月17日
题目大意,给你一个数K(4
<= K <= 10^100)和一个 L(2<=L<=10^6),K是由两个因子组成,若K最小的因子大于等于L,输出 GOOD,否则输出BAD和这个小于L的因子。多组输入,最多20组。
K这个数很大,不能用基本的数据类型处理,应用高精度来做,用一个字符数组来模拟。很容易想到的一个做法是,用高精度模拟出这个数,然后枚举K的因子x(2-
L),若K除这个数x等于0,则就找到一个K的因子x,并且这个因子是小于L的,所以输出BAD x。若没有找到一个x能被K整除,则输出GOOD。分析一下时间复杂 度,对于每个K需要枚举的数是2-L这个范围,这里就是100*10^6,还有20组测试数据,所以总的时间复杂度是O(20*100*10^6),题目限制是3000MS,很明 显这里是过不了的。这里有一个优化方法,就是用埃氏素筛法将2-10^6的素数筛 选出来放在prim[]数组里,对于每个K,只需枚举2-L之间的素数就可以了,这 样你还是不能AC。还可以做一个优化,用一个10^12进制的数来模拟这个K。
所以,解决此题的方法:高精度模拟,用埃氏素筛将2-10^5的数筛选出来,用10^12进制模拟。
贴出代码,供大家参考。
![](http://img.blog.csdn.net/20150609230058109?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvUm95ZWNvZGU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
题目大意,给你一个数K(4
<= K <= 10^100)和一个 L(2<=L<=10^6),K是由两个因子组成,若K最小的因子大于等于L,输出 GOOD,否则输出BAD和这个小于L的因子。多组输入,最多20组。
K这个数很大,不能用基本的数据类型处理,应用高精度来做,用一个字符数组来模拟。很容易想到的一个做法是,用高精度模拟出这个数,然后枚举K的因子x(2-
L),若K除这个数x等于0,则就找到一个K的因子x,并且这个因子是小于L的,所以输出BAD x。若没有找到一个x能被K整除,则输出GOOD。分析一下时间复杂 度,对于每个K需要枚举的数是2-L这个范围,这里就是100*10^6,还有20组测试数据,所以总的时间复杂度是O(20*100*10^6),题目限制是3000MS,很明 显这里是过不了的。这里有一个优化方法,就是用埃氏素筛法将2-10^6的素数筛 选出来放在prim[]数组里,对于每个K,只需枚举2-L之间的素数就可以了,这 样你还是不能AC。还可以做一个优化,用一个10^12进制的数来模拟这个K。
所以,解决此题的方法:高精度模拟,用埃氏素筛将2-10^5的数筛选出来,用10^12进制模拟。
贴出代码,供大家参考。
#include <cstdio> #include <cstring> #define maxn 1000007 #define MAXN 101 #define LL long long LL prim[maxn]; LL arr[MAXN]; bool is_prim[maxn]; int Init() { for(int i = 2; i * i < maxn; ++i) { if(!is_prim[i]) for(int j = 2 * i; j < maxn; j += i) is_prim[j] = true; } int pos = 0; for(LL i = 2; i < maxn; ++i) if(!is_prim[i]) prim[pos++] = i; return pos; } int main() { int N = Init(); char ch[MAXN]; int L; while(scanf("%s%d", ch, &L), ch[0] != '0', L) { int len = strlen(ch), pos = 0, num = 12, p = len % num; LL val = 1; while(p--) val *= 10; for(int i = 0; i < len; i += num) { LL val = 0; for(int j = i; j < i + num && j < len; ++j) val = val * 10 + ch[j] - '0'; arr[pos++] = val; } bool flag = true; for(int i = 0; prim[i] < L && i < N; ++i) { LL Mod = 0; for(int j = 0; j < pos; ++j) { if(j != pos - 1) Mod = (Mod * 1000000000000 + arr[j]) % prim[i]; else Mod = (Mod * val + arr[j]) % prim[i]; } if(Mod == 0) { printf("BAD %d\n", prim[i]); flag = false; break; } } if(flag) puts("GOOD"); } return 0; }
相关文章推荐
- Android程序Crash异常处理
- GTK--布局管理
- Caffe —— Deep learning in Practice
- jQuery EasyUI动态添加控件或者ajax加载页面后不能自动渲染问题的解决方法
- 用java将excel中数据导入mysql
- 07.linux系统管理命令
- NSTimer 的暂停与恢复运行。
- 精简的反序打印某个数
- Linux基本目录结构
- Object-c内存管理简介
- plus one
- java api sort的使用
- 20135227黄晓妍实验四
- 定时器-NSTimer
- 向产品宣战——开发者眼中的Android UI Design
- Python:mechanize模拟浏览器行为
- 自动登录和记住密码
- 抓取http://www.proxy.com.ru
- 从oracle迁移到DB2(windows版)
- hiho第二周——Trie树