この問題から計算量の意識が必要となります。
たとえば、 をそれぞれ から まで回し、 がそれぞれ素数であるかの判定をすると計算量は となってしまい、 TLE
となってしまいます。(素数判定を で行っても TLE
します。)
では、素数を事前に列挙しておき、素数に限定して を探索することにします。(エストラテネスの篩を使うことで、 以下の素数を で列挙できます。)
を 以下の素数の個数としたとき、 を回しても計算量は となります。
最後に、 で表せる数字 (個数を とします)をソートするので計算量は となり、本問題を解くことが出来ます。
実際には制約下の最大ケースで、 となるので、計算ステップは約 となります。
def prime_L(n): is_prime = [True] * (n + 1) is_prime[0] = False is_prime[1] = False for i in range(2, int(n**0.5) + 1): if not is_prime[i]: continue for j in range(i * 2, n + 1, i): is_prime[j] = False return [i for i in range(n + 1) if is_prime[i]] k,x = map(int,input().split()) L = prime_L(k) l = len(L) S = set() for i in range(l): for j in range(l): S.add(L[i]+L[j]) S = list(S) S.sort() print(S[x-1])
#include <bits/stdc++.h> using namespace std; signed main() { int k, x; cin >> k >> x; vector<int> primes; for (int i = 2; i <= k; i++) { bool is_prime = 1; for (int j = 2; j < i; j++) { if (i % j == 0) { is_prime = 0; break; } } if (is_prime) primes.push_back(i); } set<int> prime_sum; int n = primes.size(); for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { prime_sum.insert(primes[i] + primes[j]); } auto it = prime_sum.begin(); for (int i = 0; i < x - 1; i++) it++; cout << *it << endl; }