【USACO】sprime
有了前面的基础,做这道题真是so easy啊。 因为要分解后每个数都是素数,所以采用先生成短的素数,长的素数在短素数的基础上生成。 比如长度为1的素数只有 2 3 5 7, 那么符合要求的长度为2的素数只可能是 21- 29 31-39 51-59 71-79 对其他长度类似。 答案的思路和我的差不多,不过更精细一些。 在增加长度时只用考虑1 3 7 9四个尾数就行了,其他都会被2或5整除。 我没有用递归,答案用了递归。 这个说不上哪个好, 我觉得尽量避开递归比较好吧,之前递归总是容易溢出。
一次就AC的代码~
#include <stdio.h> int sp[8][100] = {0}; //全局变量 用于存放已经生成的每个长度的超级素数 int l[8] = {0}; //记录每个长度的超级素数有多少个 int isprime(int N) { int i; if(N == 2) return 1; for(i = 2; i * i <= N; i++) { if(N % i == 0) return 0; } return 1; } int generate(int n) { if(n == 1) { sp[n-1][0] = 2; sp[n-1][1] = 3; sp[n-1][2] = 5; sp[n-1][3] = 7; l[n - 1] = 4; } else { int i, j, num; for(i = 0; i < l[n - 2]; i++) { for(j = 1; j <= 9; j++) { num = sp[n - 2][i] * 10 + j; if(isprime(num)) { sp[n - 1][l[n - 1]] = num; l[n - 1]++; } } } } return 0; } int main() { FILE *in, *out; in = fopen("sprime.in", "r"); out = fopen("sprime.out", "w"); int N; fscanf(in, "%d", &N); int i; for(i = 1; i<= N; i++) { generate(i); } for(i = 0; i < l[N - 1]; i++) { fprintf(out, "%d\n", sp[N - 1][i]); } }