打素数表+快速幂取模。
题目较简单,只要数字满足其不是素数且利用“Fermat test”方法证明所有情况下均满足,则其为Carmichael Numbers。注意数字范围,分治求幂模时要用long long。
代码如下:
#include <cstdio>
#include <cmath>
#include <cstring>
bool vis[65002];
void Is_Prime(int n)//打素数表
{
memset(vis, false, sizeof(vis));
int m = sqrt(n+0.5);
for(int i=2; i<=m; i++)
if(!vis[i])
{
for(int j=i*i; j<=n; j+=i)
vis[j] = true;
}
}
int pow_mod(int a, int n, int num)//快速幂取模
{
if(n == 1)
return a;
int x = pow_mod(a, n/2, num);
long long ans = (long long)x * x % num;
if(n%2 == 1)
ans = (ans * a) % num;
return (int)ans;
}
bool Judge_CarNumber(int num)//判断是否为Carmichael Numbers
{
int ans;
for(int i=2; i<num; i++)
{
ans = pow_mod(i, num, num);
if(ans != i)
return false;
}
return true;
}
int main()
{
#ifdef test
freopen("sample.txt", "r", stdin);
#endif
int num;
Is_Prime(65000);
while(scanf("%d", &num) && num)
{
if(vis[num] && Judge_CarNumber(num))
printf("The number %d is a Carmichael number.\n", num);
else
printf("%d is normal.\n", num);
}
return 0;
}