USACO section 1.5.3 SuperPrime Rib

1.
从数学的角度: 1.首位只能是质数2 3 5 7
2.其余位只能是1,3,7,9
3.若n=1,直接输出2,3,5 7

直接DFS 1~9,加入当前数末尾,并判断是不是素数,是则递归处理下一位数,不是则回溯,直到depth>n。不会超时。

2. 这道题折磨了我好久,一直出现

Execution error: Your program (`sprime') exited with signal #11 (segmentation violation [maybe caused by accessing memory out of bounds, array indexing out of bounds, using a bad pointer (failed open(), failed malloc), or going over the maximum specified memory limit]). The program ran for 0.000 CPU seconds before the signal. It used 3188 KB of memory. 

但是当把定义文件输入输出流放在全局变量的时候,就AC了。。。。不明原因。。。。

2. 以下是代码

/*
ID: dollar4
PROG: sprime
LANG: C++
*/
#include <fstream>
#include <cmath>

using namespace std;
int num[5000] = {2, 3, 5, 7};
ofstream fout ("sprime.out");
ifstream fin ("sprime.in");
int check(int a)
{
    for (int i = 3; i * i <= a; i += 2)
        if (a % i == 0)
            return 0;
    return 1;
}
int main()
{

    int n, i;
//    memset(num, 0, sizeof(num));
//    num[0] = 2;
//    num[1] = 3;
//    num[2] = 5;
//    num[3] = 7;
    fin >> n;
    int front = 0;
    int rear = 4;
    int maxn = pow(10.0, n);
    int minn = maxn / 10;
    while (front < rear)
    {
        int k = num[front++];
        if (check(k * 10 + 1))
            num[rear++] = k * 10 + 1;
        if (check(k * 10 + 3))
            num[rear++] = k * 10 + 3;
        if (check(k * 10 + 7))
            num[rear++] = k * 10 + 7;
        if (check(k * 10 + 9))
            num[rear++] = k * 10 + 9;
        if (num[rear-1] > maxn - 1)
            break;
    }
    for (i = 0; num[i] < maxn; i++)
        if (num[i] >= minn)
            fout << num[i] << endl;
    return 0;
}

4. 官方参考代码:

We use a recursive search to build superprimes of length n from superprimes of length n-1 by adding a 1, 3, 7, or 9. (Numbers ending in any other digit are divisible by 2 or 5.) Since there are so few numbers being tested, a simple primality test suffices.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

FILE *fout;

int
isprime(int n)
{
	int i;

	if(n == 2)
		return 1;

	if(n%2 == 0)
		return 0;

	for(i=3; i*i <= n; i+=2)
		if(n%i == 0)
			return 0;

	return 1;
}

/* print all sprimes possible by adding ndigit digits to the number n */
void
sprime(int n, int ndigit)
{
	if(ndigit == 0) {
		fprintf(fout, "%d\n", n);
		return;
	}

	n *= 10;
	if(isprime(n+1))
		sprime(n+1, ndigit-1);
	if(isprime(n+3))
		sprime(n+3, ndigit-1);
	if(isprime(n+7))
		sprime(n+7, ndigit-1);
	if(isprime(n+9))
		sprime(n+9, ndigit-1);
}

void
main(void)
{
	int n;
	FILE *fin;

	fin = fopen("sprime.in", "r");
	assert(fin != NULL);
	fout = fopen("sprime.out", "w");
	assert(fout != NULL);

	fscanf(fin, "%d", &n);

	sprime(2, n-1);
	sprime(3, n-1);
	sprime(5, n-1);
	sprime(7, n-1);
	exit (0);
}


原文地址:https://www.cnblogs.com/dollarzhaole/p/3188909.html