标签:10006 ll number 素数 Numbers 测试 UVA 密码学 mod
题目描述:
当今计算机科学的一个重要的领域就是密码学。有些人甚至认为密码学是计算机科学中唯一重要的领域,没有密码学生命都没有意义。
阿尔瓦罗就是这样的一个人,它正在设计一个为西班牙杂烩菜饭加密的步骤。他在加密算法中应用了一些非常大的素数。然而确认一个非常大的数是不是素数并不是那么简单。一个费时的方法是用比这个数的平方根小的所有素数去除它,对于大整数来说,这样一定会毁掉这个杂烩菜饭的。
然而,一些很有信心耗时少的随机测试存在,其中一个就是费马测试。
在2和n-1之间随机选取一个数(n是我们要测试的数)。如果 mod n = a 成立,n就可能是一个素数。
如果一个数通过费马测试很多次那么它就很可能是一个素数。
不幸的是,一些数不是素数但是它们依然能通过每一个比它小的数的费马测试。这些数被称作卡迈克尔数
这道题要求你写一个程序去测试给定的数是不是一个卡迈克尔数。
完成了这个任务的队伍有希望接受来自阿尔瓦罗的西班牙杂烩菜饭23333
Input
多组输入,第一行给一个n (2 < n < 65000) 。n = 0 表示输入结束并不需要处理
Output
对每组输入,输出它是不是卡迈克尔数,参考样例。
Sample Input
1729
17
561
1109
431
0
Sample Output
The number 1729 is a Carmichael number.
17 is normal.
The number 561 is a Carmichael number.
1109 is normal.
431 is normal.
解题报告:
1:首先明确一点,素数也能满足这个条件。根据题意应该先判断这个数是不是素数。
2:套用快速幂模板判断就行了。注意技巧和顺序,避免超时。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll Pow(ll base, ll n, ll mod){
ll ans = 1;
while(n){
if(n&1)ans = ans*base%mod;
n >>= 1, base = base*base%mod;
}
return ans%mod;
}
inline ll isPrime(ll n){
if(n == 2 || n == 3)return 1;
if( (n == 1) || (n%6 != 1 && n%6 != 5) )return 0;
ll s = sqrt(n);
for(ll i=5; i<=s; i+=6)
if(n%i==0 || n%(i+2)==0)return 0;
return 1;
}
int main(){
ll n;
while(~scanf("%lld", &n) && n){
if(isPrime(n)){
printf("%lld is normal.\n", n);
continue;
}
ll flag = 1;
for(ll i=2; i<=n-1; ++i){
if(Pow(i, n, n) != i){
flag = -1;
break;
}
}
if(flag == -1)
printf("%lld is normal.\n", n);
else
printf("The number %lld is a Carmichael number.\n", n);
}
return 0;
}
baronLJ 发布了149 篇原创文章 · 获赞 4 · 访问量 1万+ 私信 关注
标签:10006,ll,number,素数,Numbers,测试,UVA,密码学,mod 来源: https://blog.csdn.net/jun_____/article/details/104072318
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。