原题
对于一个长度为 n 的正整数序列 a1,a2,…,an,我们这样规定该序列的价值:
- 如果 n 为偶数,则序列价值为 gcd(
,
)+gcd(
,
)+…+gcd(
,
)。
- 如果 n 为奇数,则序列价值为 gcd(
,
)+gcd(
,
)+…+gcd(
,
)。
请你构造一个长度为 nn 的正整数序列 a1,a2,…,an,要求:
- ai 两两不同。
- 1 ≤ ai ≤
。
- 序列价值恰好为 m。
输入格式
共一行,两个整数 n,m。
输出格式
共一行,如果序列不存在,则输出 -1
,否则输出 a1,a2,…,an。
如果答案不唯一,输出任意合理答案均可。
数据范围
前 7 个测试点满足 1 ≤ n ≤ 10。
所有测试点满足 1 ≤ n ≤ ,0 ≤ m ≤
。
输入样例1:
5 2
输出样例1:
1 2 3 4 5
输入样例2:
5 3
输出样例2:
2 4 3 7 1
输入样例3:
7 2
输出样例3:
-1
题意解读:
我们构造一个序列需要满足:
如果 n 为偶数 gcd(,
)+gcd(
,
)+…+gcd(
,
) 相加和为 m
如果 n 为奇数 gcd(,
)+gcd(
,
)+…+gcd(
,
) 相加和为 m
解题思路:
分析上述式子 序列价值求和的个数为 (n / 2) 个,所以 m 需要满足 m >= (n / 2)
我们不妨设 = d,那么 gcd(
,
) = d,后序数列 gcd(
,
) 或者 gcd(
,
) 只需等于 1 即可
那么 d = m - (n / 2 - 1) 解释:
(n / 2) 代表一共有几个gcd相加,
减去 1 表示 gcd(,
) 腾出位置,
m - (n / 2 - 1) 给 gcd(,
)赋一个值,使后面序列的gcd为 1
代码实现:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
int n,m;
cin >> n >> m;
if(n == 1) // n = 1的时候需要特判 只有 m = 0 的时候才符合
{
if(m == 0) puts("1"); // m = 0时,输出任意数都可
else puts("-1"); // 不符合,抛出 -1
}
else if(m < n / 2) puts("-1");
else
{
int d = m - (n / 2 - 1);
printf("%d %d ",d,2*d); // 先输出 a1, a2
for(int i = 1;i < n - 1;i++) printf("%d ",2 * d + i); //后面的数满足gcd = 1
}
return 0;
}