E Easy Construction
题目链接:https://ac.nowcoder.com/acm/contest/5671/E
题目描述
Roundgod is given
n
,
k
n_{}, k_{}
n,k, construct a permutation
P
P
P of
1
∼
n
1\sim n
1∼n satisfying that for all integers
i
i_{}
i in
[
1
,
n
]
[1, n]_{}
[1,n] , there exists a contiguous subarray in
P
P
P of length
i
i_{}
i whose sum is
k
k
k modulo
n
n
n. If there are multiple solutions, print any of them. If there is no solution, print “-1” in one line.
输入描述:
The first line contains two integers
n
,
k
(
1
≤
n
≤
5000
,
0
≤
k
<
n
)
n, k~(1\le n \le 5000, 0\le k < n)
n,k (1≤n≤5000,0≤k<n).
输出描述:
Print
n
n_{}
n integers, the answer permutation in one line if such permutation exists, or print “-1” in one line if no solution exists.
示例1
输入
2 1
输出
1 2
说明
The sum of subintervals
[
1
]
,
[
1
,
2
]
[1],[1,2]
[1],[1,2] both satisfy
≡
1
(
m
o
d
2
)
\equiv 1 \pmod{2}
≡1(mod2), and their lengths are
1
,
2
1,2
1,2 respectively.
示例2
输入
3 1
输出
-1
题面
思路
题解:
首先我们判断一下什么时候有解。
我们可以发现要想有解,那么最大的一个子区间必须满足条件,而长度为 n 的子区间只有一个,也就是 P 本身,而 P 本身的元素和就是
n
⋅
(
n
+
1
)
2
{n\cdot(n+1)}\over {2}
2n⋅(n+1),即
k
k
k 必须等于
n
⋅
(
n
+
1
)
2
{n\cdot(n+1)}\over {2}
2n⋅(n+1)
%
n
\%n
%n 。
然后假设整数
k
k
k 满足上述条件,这时候是否有解呢?
此时的
k
=
n
⋅
(
n
+
1
)
2
%
n
=
(
(
n
2
%
n
)
×
(
(
n
+
1
)
%
n
)
)
%
n
=
n
2
%
n
=
n
2
k={n\cdot (n+1) \over 2} \% n = {( ({n\over 2}\%n) \times ({(n+1) }\% n) ) }\% n={n\over 2 }\% n = {n\over2}
k=2n⋅(n+1)%n=((2n%n)×((n+1)%n))%n=2n%n=2n
①
I
f
If
If n 是奇数
则
k
=
0
k=0
k=0
令
P
=
{
n
,
1
,
n
−
1
,
2
,
n
−
2
,
…
}
P = \{n, 1, n-1, 2, n-2, …\}
P={n,1,n−1,2,n−2,…} 这样排列即可。
只需要后面的每两个加起来为 n 即可。
此时,若
i
i
i 为奇数:取第
1
∼
i
1 \sim i
1∼i个即可,此时的和为
(
i
2
+
1
)
n
({i\over 2}+1)n
(2i+1)n则
%
n
=
0
=
k
\%n=0=k
%n=0=k,若
i
i
i 为偶数:就取第
2
∼
i
+
1
2 \sim i+1
2∼i+1个.
①
I
f
If
If n 是偶数
则
k
=
n
2
k={n\over2}
k=2n,
令
P
=
{
n
,
n
2
,
1
,
n
−
1
,
2
,
n
−
2
,
…
}
P = \{n, {n\over2}, 1, n-1, 2, n-2, …\}
P={n,2n,1,n−1,2,n−2,…} 即可;
只需要前面有个 n 和
n
2
n\over 2
2n 后面的每两个加起来为 n 即可。
此时,若
i
i
i 为奇数:就取第
2
∼
i
+
1
2 \sim i+1
2∼i+1个,若
i
i
i 为偶数:就取第
1
∼
i
1 ~\sim i
1 ∼i个。
至此,可以知道假设的情况下有解,故判断是否有解的条件就是 k k k是否满足 n 2 n\over 2 2n 。
代码
#include <bits/stdc++.h>
const int N = 5e3 + 5;
int n, k, ans[N];
int main()
{
scanf("%d%d", &n, &k);
if ((n % 2 == 0 && k != n / 2) || (n % 2 == 1 && k != 0)) {
printf("-1\n");
return 0;
}
ans[n] = n;
if (n % 2 == 0) {
ans[n - 1] = k;
int x = k - 1, y = k + 1;
for (int i = 1; i + 1 < n - 1; i += 2) {
ans[i] = x--;
ans[i + 1] = y++;
}
} else {
int x = n / 2, y = n / 2 + 1;
for (int i = 1; i + 1 < n; i += 2) {
ans[i] = x--;
ans[i + 1] = y++;
}
}
for (int i = 1; i <= n; i++) {
printf("%d ", ans[i]);
}
return 0;
}
或直接输出
#include <cstdio>
int n, k;
int main()
{
scanf("%d%d", &n, &k);
if (k != (n * (n - 1) / 2) % n){ //如果k不满足条件
printf("-1");
}else{
printf("%d", n);
if ((n & 1) == 0){ //如果是偶数
printf(" %d", n / 2);
}
for (int i = 1; i * 2 < n; i ++){
printf(" %d %d", i, n - i);
}
}
return 0;
}