暂无链接
喝牛奶
题目描述
这一天 T o m Tom Tom 正在喝牛奶。
T o m Tom Tom的主人买来了 n n n 桶牛奶,第 i i i桶牛奶的重量是 i i i吨。由于主人心情不好,她随机地把这些牛奶的顺序打乱了,然后把它们丢给了 T o m Tom Tom。
T o m Tom Tom 会从第一桶牛奶开始喝,每次喝完一整桶牛奶,由于猫的消化能力及其强大,所以每当 T o m Tom Tom的肚子里有 n n n吨牛奶时,他会开启究极消化模式,把肚子中的牛奶清零。与此同时,在喝完每一桶牛奶后,他会记录下自己肚子里剩余牛奶的重量 w w w,并从主人那里领取一张写着数字 w w w的卡片,显然 w ∈ [ 0 , n − 1 ] w∈[0,n−1] w∈[0,n−1]。
由于 T o m Tom Tom是一只十分好学的好猫,在日复一日的喝牛奶活动中,他渐渐开始好奇,是否存在某一些给定牛奶的顺序,使得 T o m Tom Tom可以集齐全部的 n n n 种卡片?
本来 T o m Tom Tom 想问你有多少种这样的方案,但是由于他牛奶喝多了,自己也无法解决这个问题,所以,他现在准备请你给出一种或两种可以使得他集齐所有卡片的给定牛奶的顺序。
一句话题意: 请构造两个 1 ∼ n 1∼n 1∼n的排列,使得在模 n n n意义下对这个排列进行前缀和操作后, 0 n − 1 0 ~ n−1 0 n−1中的每个数在新的序列中都出现了一次。如果没有这样的排列,请输出 − 1 −1 −1。
输入格式
一个正整数 n n n 。
输出格式
第一行一个数字: − 1 −1 −1 或 1 1 1或 2 2 2 。
如果你输出了 − 1 −1 −1,则代表你认为不存在这样的排列。
如果你输出了 1 1 1,则代表你即将输出一个这样的排列。
如果你输出了 2 2 2,则代表你即将输出两个这样的排列。
如果你在第一行输出了 1 1 1或 2 2 2,那么你需要输出 ( 一行,一个 1 n 1~n 1 n的排列 ) 或 (两行,两个不相同的 1 n 1~n 1 n的排列) 。
数据保证如果存在这样的排列,则至少有两个合法的排列。
输入样例
6
输出样例
2
6 2 5 3 1 4
6 5 2 3 4 1
数据范围
对于 10 % 10\% 10%的数据,保证 2 < n ≤ 8 2<n≤8 2<n≤8
对于 30 % 30\% 30%的数据,保证 2 < n ≤ 12 2<n≤12 2<n≤12
对于 100 % 100\% 100%的数据,保证 2 < n ≤ 200000 2<n≤200000 2<n≤200000
评分标准
本题使用
s
p
e
c
i
a
l
j
u
d
g
e
special\ judge
special judge 进行评测。
如果你的输出不符合输出格式或者答案错误,那么你将获得本测试点
0
%
0\%
0% 的分数。
如果你输出了一个正确排列和一个错误排列,那么你将获得本测试点
0
%
0\%
0% 的分数。
如果你只输出了一个正确排列,那么你将获得本测试点
40
%
40\%
40% 的分数。
如果你的程序正确地输出了结果,那么你将获得本测试点
100
%
100\%
100% 的分数。
如果你的程序导致
s
p
e
c
i
a
l
j
u
d
g
e
special\ judge
special judge 出现异常,那么你将会获得该测试点
0
%
0\%
0% 的分数(包括但不仅限于输出的东西不是一个排列、第一行输出了奇怪的东西、输出的排列中加入了奇怪的字符等)
题解
可能需要打表找一找规律?
由于题目保证如果有答案的话至少有两个合法排列,所以我们不用考虑 n = 1 或 2 n=1或2 n=1或2的情况,直接看 n ≥ 3 n\ge 3 n≥3的。
首先,如果 n n n放在排列中间,那么肯定会有两个一样的前缀和,所以 n n n一定要放在开头。
当 n n n为奇数时,由于 n n n一定在第一个, ∑ i = 1 n i ≡ 0 m o d    n \sum_{i=1}^ni\equiv0\mod n ∑i=1ni≡0modn所以后面一定有两个重复的数,输出 − 1 -1 −1。
那么只剩
n
n
n为偶数的情况,为了让模意义下的前缀和不重不漏,不妨将数两两分为一组,使每一组和为
n
+
1
n+1
n+1:
n
,
(
n
−
1
,
2
)
,
(
n
−
3
,
4
)
,
⋯
 
,
1
n,(n-1,2),(n-3,4),\cdots,1
n,(n−1,2),(n−3,4),⋯,1
第二组的话,我们可以让每组的数字和为
n
−
1
n-1
n−1:
n
,
(
1
,
n
−
2
)
,
(
3
,
n
−
4
)
,
⋯
 
,
n
−
1
n,(1,n-2),(3,n-4),\cdots,n-1
n,(1,n−2),(3,n−4),⋯,n−1
代码
#include<cstdio>
int n;
void in(){scanf("%d",&n);}
void ac()
{
if(n&1){puts("-1");return;}
printf("2\n%d ",n);for(int i=1;i<n-1;i+=2)printf("%d %d ",n-i,i+1);puts("1");
printf("%d ",n);for(int i=1;i<n-1;i+=2)printf("%d %d ",i,n-i-1);printf("%d",n-1);
}
main(){in(),ac();}