Summing to a Square Prime-CSDN博客

52 阅读1分钟

Summing to a Square Prime\

现在很少在这个博客上贴题解了,贴这个题是因为这道题的数据给的真的是太巧妙了,出题人费尽心机呀。先分析数据再给题面

1 < Sp2(n) < 7994. 线性素数筛的小于7994的质数有1007个

而进一步筛得平方素数刚好500整个,那个7994是有500推出来的吧 :)

测试组数也是500,询问第n个平方素数,n的上界也是500,这种巧合,只能说god knows the reason.

接着划分平方素数,由于每个划分数为1或2或3。不用动态规划也很很快出结果。


\

CZ_PROB1 - Summing to a Square Prime

#math  #dynamic-programming

\

SP2={p∣p:prime∧(∃x1,x2∈Z,p=x21+x22)} SP2={p∣p:prime∧(∃x1,x2∈Z,p=x12+x22)} is the set of all primes that can be represented as the sum of two squares. The function  SP2(n) SP2(n) gives the  n nth prime number from the set  SP2 SP2. Now, given two integers  n n ( 0<n<501 0<n<501) and  k k ( 0<k<4 0<k<4), find  p(SP2(n),k) p(SP2(n),k) where  p(a,b) p(a,b) gives the number of unordered ways to sum to the given total ‘ a a’ with ‘ b b’ as its largest possible part. For example:  p(5,2)=3 p(5,2)=3 (i.e.  2+2+1 2+2+1,  2+1+1+1 2+1+1+1, and  1+1+1+1+1 1+1+1+1+1). Here  5 5 is the total with  2 2 as its largest possible part.

Input

The first line gives the number of test cases  T T followed by  T T lines of integer pairs,  n n and  k k.

Constraints

  • 0<T<501 0<T<501
  • 0<n<501 0<n<501
  • 1<SP2(n)<7994 1<SP2(n)<7994
  • 0<k<4 0<k<4

Output

The  p(SP2(n),k) p(SP2(n),k) for each  n n and  k k. Append a newline character to every test cases’ answer.

Example

Input:
3
2 2
3 2
5 3

Output:
3
7
85

 Submit solution!


\

\

#include <cstdio>
#include <algorithm> 
#include <cmath>
#include <cstring>
using namespace std;
const int N = 7994, M = 89;
char v[N];
int p[1007];
int getPrime(int n) {
	memset(v + 2, 1, sizeof v);
	int cur = 0;
	for (int i = 2; i <= n; ++i) {
		if(v[i]) p[cur++] = i;
		for (int j = 0; j < cur && (i * p[j] <= n); ++j) {
			v[i * p[j]] = 0;
			if(i % p[j] == 0) break;
		}
	}
	return cur;
}
int work(int n, int k) {
	if(k == 1) return 1;
	int cnt2 = n >> 1;
	if(k == 2) return cnt2 + 1;
	int cnt3 = n / 3, res = 0;
	for (int i = 1; i <= cnt3; i++) 
		res += (n - i * 3) / 2;
	return 1 + cnt2 + cnt3 + res;	
}
int main()
{
	getPrime(N - 1); // 1007个素数 .x <= 89
	int cnt = 0;
	for (int i = 1; i <= M; ++i) 
		for (int j = i; j <= M; ++j) {
			int tmp = i * i + j * j;
			if(tmp < N && v[tmp]) p[++cnt] = tmp;
		} //刚好500个,题目数据范围也是500,巧了啊 
	sort(p + 1, p + cnt + 1);
	//for (int i = 1; i <= cnt; ++i) printf("%d%c", p[i], " \n"[i == cnt]);
	int T;
	scanf("%d", &T);
	while(T--) {
		int n, k;
		scanf("%d%d", &n, &k);
		printf("%d\n", work(p[n], k)); //k = 1, 2, 3
	} 

    return 0;
}


其实这个spoj界面比较好看。