#include using namespace std; // 判断素数的函数(这里数值较小,用简单方法即可) bool isPrime(int x) { if(x < 2) return false; for (int i = 2; i * i <= x; i++){ if(x % i == 0) return false; } return true; } // 主函数 int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int K; cin >> K; // 注意:题目要求 0 <= K <= 10000 // 构造思路: // 将数列分为两个模块: // 模块 P:用数字 1;它们之间任一数对之和为 1+1 = 2 (素数)。 // 模块 Q:将另外一部分再分为两组, // 分别赋值为 3 和 8。因为 3+8 = 11 是素数, // 而 3+3 = 6、8+8 = 16 均为合数。 // 同时保证模块 P 与模块 Q 的混合配对均为合数: // 1+3 = 4, 1+8 = 9. // // 因此如果模块 P 中有 x 个 1, // 它们贡献的素数对为 C(x,2) = x*(x-1)/2; // 如果模块 Q 中左侧(数字3)的个数为 a, // 右侧(数字8)的个数为 b,则贡献素数对为 a*b. // // 总数对数为: x*(x-1)/2 + a*b = K. // 同时序列总长度: N = x + a + b (要求 N <= 250). // // 接下来遍历 x, a, b 寻找满足条件的一个解: // 特殊处理 K == 0:至少输出一个数(例如 1)即可,因为没有任何两数之和要为素数。 if(K == 0){ cout << 1 << "\n" << 1 << "\n"; return 0; } bool found = false; int X = -1, A = -1, B = -1; // x取值范围 0 <= x <= 250 for (int x = 0; x <= 250 && !found; x++){ // 模块 P 内贡献: x*(x-1)/2 int base = x * (x - 1) / 2; // 若 base > K,则后面x更大时肯定超出 K if(base > K) break; // 接下来求 a, b 非负整数使得: // base + a*b = K <==> a*b = (K - base) int rem = K - base; // 枚举 a,从 0 到 (250 - x)(因为后面 a+b 要加上 x 不超过 250) for (int a = 0; a <= 250 - x && !found; a++){ // 如果 a 为0,则 a*b 为0,因此只有当 rem==0时可行,此时 b 必须为 0; // 但注意 K>0时 rem > 0,所以 a==0只能用于 K==base (即 K为三角形数)。 if(a == 0){ if(rem == 0){ // 令 b = 0 int b = 0; if(x + a + b <= 250 && x + a + b >= 1){ X = x; A = a; B = b; found = true; } } continue; } // 当 a > 0 时,要求 rem 必须能被 a 整除 if(rem % a != 0) continue; int b = rem / a; // 同时要求 a+b 不超过 (250 - x) if(a + b <= 250 - x){ X = x; A = a; B = b; found = true; break; } } } if(!found){ //按照题目范围,通常总能构造出解(下面这种构造满足题意)。 cout << -1 << "\n"; return 0; } int N = X + A + B; cout << N << "\n"; // 根据构造方案,序列分为两块: // 模块 P:输出 X 个 1; // 模块 Q:输出 A 个 3 和 B 个 8. // 数值范围内均满足 1 <= c_i <= 1000000. // 输出模块 P for (int i = 0; i < X; i++){ cout << 1 << " "; } // 输出模块 Q:先 A 个 3 for (int i = 0; i < A; i++){ cout << 3 << " "; } // 再 B 个 8 for (int i = 0; i < B; i++){ cout << 8 << " "; } cout << "\n"; return 0; }