結果
| 問題 | No.689 E869120 and Constructing Array 3 |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-11-18 03:43:07 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 1,000 ms |
| コード長 | 3,712 bytes |
| コンパイル時間 | 1,510 ms |
| コンパイル使用メモリ | 162,836 KB |
| 実行使用メモリ | 7,848 KB |
| 最終ジャッジ日時 | 2025-11-18 03:43:10 |
| 合計ジャッジ時間 | 3,073 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 13 |
ソースコード
#include <bits/stdc++.h>
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;
}