2012-03-16 21:52:29Morris

[UVA][D&C] 10006 - Carmichael Numbers

 Carmichael Numbers 

An important topic nowadays in computer science is cryptography. Some people even thinkthat cryptography is the only important field in computer science, and thatlife would not matter at all without cryptography.Alvaro is one of such persons, and is designing a set of cryptographicprocedures for cooking paella. Some of the cryptographic algorithms he isimplementing make use of big prime numbers. However, checking if a big numberis prime is not so easy. An exhaustive approach can require the division ofthe number by all the prime numbers smaller or equal than its square root. Forbig numbers, the amount of time and storage needed for such operations wouldcertainly ruin the paella.

However, some probabilistic tests exist that offerhigh confidence at low cost. One of them is the Fermat test.

Let a be a random number between 2 and n - 1 (being n the number whoseprimality we are testing). Then, n is probably prime if the followingequation holds:

begin{displaymath}a^n bmod n = aend{displaymath}

If a number passes the Fermat test several times then it is prime with a high probability.

Unfortunately, there are bad news. Some numbers that are not prime still passthe Fermat test with every number smaller than themselves. These numbers arecalled Carmichael numbers.

In this problem you are asked to write a program to test if a given number isa Carmichael number. Hopefully, the teams that fulfill the task will one day beable to taste a delicious portion of encrypted paella. As a side note, we needto mention that, according to Alvaro, themain advantage of encrypted paella over conventional paella is that nobody but you knowswhat you are eating.

Input 

The input will consist of a series of lines, eachcontaining a small positive number n (2 < n < 65000). A number n = 0 willmark the end of the input, and must not be processed.

Output 

For each number in theinput, you have to print if it is a Carmichael number or not, as shown in thesample 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.


做法 : D&C,
先判定非質數, 再去做 check
#include <stdio.h>
#include <stdlib.h>
char Prime[65001] = {};
void sieve() {
int i, j;
for(i = 2; i < 65000; i++) {
if(Prime[i] == 0) {
for(j = 2; i*j < 65000; j++)
Prime[i*j] = 1;
}
}
}
long long mod(long long x, long long y, long long m) {
long long tmp = x, ans = 1;
while(y) {
if(y&1) {
ans *= tmp;
ans %= m;
}
tmp = tmp*tmp, tmp %= m;
y >>= 1;
}
return ans;
}
int Check(int n) {
int i;
for(i = 2; i <= n-1; i++) {
if(mod(i, n, n) != i)
return 0;
}
return 1;
}
int main() {
sieve();
int n;
while(scanf("%d", &n) == 1 && n) {
if(Prime[n] == 1 && Check(n) == 1)
printf("The number %d is a Carmichael number.\n", n);
else
printf("%d is normal.\n", n);
}
return 0;
}