この問題から計算量の意識が必要となります。
たとえば、 をそれぞれ から まで回し、 がそれぞれ素数であるかの判定をすると計算量は となってしまい、 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;
}