一 写在前面
1.1 本文内容
一个关于素数的神奇性质。
二 素数性质
性质:所有大于等于5的素数一定和6的倍数相邻!此性质可以被证明,证明方法可以去搜索相关资料。下面给出1000以内的素数,你可以验证一下看是不是这样。
有了这个性质,下面再给出一个其在质因数分解中的实际应用例子。题目链接在此。题目大意是给定一个正整数N,要求将其分解成多个质因数相乘的形式。需要注意的是质因数分解的常用算法是试除法,例子中使用的也是试除法。并且每一个合数都能够写成几个质因数相乘的形式。
上述题目的一个可行代码如下:
1 #include <stdio.h> 2 #include <stdbool.h> 3 4 int main(int argc, char *argv[]) 5 { 6 //freopen("in.txt", "r", stdin); 7 int n, step; 8 bool first = true; 9 10 scanf("%d", &n); 11 12 /* 将数n中包含的2, 3, 5这三个质因数给除去 */ 13 while (n % 2 == 0) 14 { 15 (first == true) ? printf("2") : printf("*2"); 16 first = false; 17 n /= 2; 18 } 19 while (n % 3 == 0) 20 { 21 (first == true) ? printf("3") : printf("*3"); 22 first = false; 23 n /= 3; 24 } 25 while (n % 5 == 0) 26 { 27 (first == true) ? printf("5") : printf("*5"); 28 first = false; 29 n /= 5; 30 } 31 32 /* 让step从6开始,考察step相邻的两个数,如果能整除n,则将其除去 */ 33 step = 6; 34 while (n >= (step-1)) 35 { 36 if (n % (step-1) == 0) 37 { 38 (first == true) ? printf("%d", step-1) : printf("*%d", step-1); 39 first = false; 40 n /= (step-1); 41 } 42 else if (n % (step+1) == 0) 43 { 44 (first == true) ? printf("%d", step+1) : printf("*%d", step+1); 45 first = false; 46 n /= (step+1); 47 } 48 else 49 { 50 step += 6; 51 } 52 } 53 54 putchar(‘\n‘); 55 //fclose(stdin); 56 return 0; 57 }
有人可能有疑问,虽然大于等于5的素数一定和6的倍数相邻,但反过来,所有与6的倍数相邻的却不一定是素数。也就是说在代码中的最后一个while循环中,step-1和step+1两个数可能是合数,那这样岂不是将n中的合数因子给除去了吗?事实果真是这样吗?不是的,前面说过,任何一个合数一定可以分解成几个质因数相乘的形式,也就是说即使step-1和step+1两个数中存在合数,那么它也无法整除n,因为在遇到该合数之前,该合数所能分解成的所有质因数都已经在n中给去除了。换句话说,在遇到n的合数因子(step-1或step+1)之前,该合数因子就因为其自身能被分解成更小的质因数而在之前的质因数分解中被分解殆尽了。所以上述代码是没问题的。