UVa 10852-Less Prime

问题描述】

设n为一个正整数,100<=n<=10000,请找到素数x,x<=n,使得n-p*x最大,其中p是整数,使得p*x<=n<=(p+1)*x。

输入:

输入的第一行给出一个整数M,表示测试用例的个数。每个测试用例一行,给一个整数N,100<=N<=10000。

输出:

对输入的每个测试用例输出一行,给出满足上述条件的素数。

样例输入 样例输出

5

4399

614

8201

101

7048

2203

311

4111

53

3527


【解题思路

    要使得n-p*x最大,(x为素数,p为整数,p*x<=n<=(p+1)*x),则x为所有小于n的素数中,被n除后余数最大的一个素数。由此可得出算法:先离线计算出[2...10000]的素数表SU[],表长为num,然后每输入一个整数n,则枚举小于n的所有素数,计算tmp=max{n%SU[i]|SU[i]<n}其中1<=i<=num,满足条件的素数即为对应tmp=n%SU[k]的素数SU[k]。


【具体实现

#include<iostream>
#include<cmath>

/*n的上下限*/
#define maxNum 10000
#define minNum 100

using namespace std;

/*素数筛*/
int SIGN[maxNum];
/*保存所有素数*/
int SU[maxNum];

int main(){
	/*离线计算出素数筛*/
	SIGN[0] = SIGN[1] = 1;
	for (int i = 2; i <= maxNum; ++i){
		for (int j = 2; j <= sqrt(i); ++j)
		if (i%j == 0)
			SIGN[i] = 1;
	}

	/*将素数筛中的素数保存至SU[]*/
	int num = 0;
	for (int k = 0; k < maxNum;++k)
	if (!SIGN[k])
		SU[num++] = k;

	int times;//输入次数
	int N;//保存待处理值
	while (cin >> times){
		for (int b = 0; b < times; ++b){
			cin >> N;

			int k = 0;//保存余数最大时的项数值a
			int tmp = 0;//保存余数最大值

			for (int a = 0; a < num - 1; ++a)
			if (SU[a] < N&&tmp < N%SU[a]){
				tmp = N%SU[a];
				k = a;
			}
			cout << SU[k] << endl;
		}	
	}

	return 0;
}


【额外补充

原来wustoj上也有UVa的题啦。



你可能感兴趣的:(题解,less,Prime,UVa10852)