[2018.11.05 T1] 喝牛奶

暫無鏈接

喝牛奶

題目描述

這一天TomTom 正在喝牛奶。

TomTom的主人買來了nn 桶牛奶,第ii桶牛奶的重量是ii噸。由於主人心情不好,她隨機地把這些牛奶的順序打亂了,然後把它們丟給了TomTom

TomTom 會從第一桶牛奶開始喝,每次喝完一整桶牛奶,由於貓的消化能力及其強大,所以每當TomTom的肚子裏有nn噸牛奶時,他會開啓究極消化模式,把肚子中的牛奶清零。與此同時,在喝完每一桶牛奶後,他會記錄下自己肚子裏剩餘牛奶的重量ww,並從主人那裏領取一張寫着數字ww的卡片,顯然w[0,n1]w∈[0,n−1]

由於TomTom是一隻十分好學的好貓,在日復一日的喝牛奶活動中,他漸漸開始好奇,是否存在某一些給定牛奶的順序,使得TomTom可以集齊全部的 nn 種卡片?

本來TomTom 想問你有多少種這樣的方案,但是由於他牛奶喝多了,自己也無法解決這個問題,所以,他現在準備請你給出一種或兩種可以使得他集齊所有卡片的給定牛奶的順序。

一句話題意: 請構造兩個 1n1∼n的排列,使得在模nn意義下對這個排列進行前綴和操作後,0 n10 ~ n−1中的每個數在新的序列中都出現了一次。如果沒有這樣的排列,請輸出1−1

輸入格式

一個正整數nn

輸出格式

第一行一個數字:1−11122

如果你輸出了1−1,則代表你認爲不存在這樣的排列。

如果你輸出了11,則代表你即將輸出一個這樣的排列。

如果你輸出了22,則代表你即將輸出兩個這樣的排列。

如果你在第一行輸出了1122,那麼你需要輸出 ( 一行,一個1 n1~n的排列 ) 或 (兩行,兩個不相同的1 n1~n的排列) 。

數據保證如果存在這樣的排列,則至少有兩個合法的排列。

輸入樣例

6

輸出樣例

2
6 2 5 3 1 4
6 5 2 3 4 1

數據範圍

對於10%10\%的數據,保證2<n82<n≤8

對於30%30\%的數據,保證 2n122<n≤12

對於100%100\%的數據,保證2<n2000002<n≤200000

評分標準

本題使用special judgespecial\ judge 進行評測。
如果你的輸出不符合輸出格式或者答案錯誤,那麼你將獲得本測試點0%0\% 的分數。
如果你輸出了一個正確排列和一個錯誤排列,那麼你將獲得本測試點0%0\% 的分數。
如果你只輸出了一個正確排列,那麼你將獲得本測試點40%40\% 的分數。
如果你的程序正確地輸出了結果,那麼你將獲得本測試點100%100\% 的分數。
如果你的程序導致special judgespecial\ judge 出現異常,那麼你將會獲得該測試點0%0\% 的分數(包括但不僅限於輸出的東西不是一個排列、第一行輸出了奇怪的東西、輸出的排列中加入了奇怪的字符等)

題解

可能需要打表找一找規律?

由於題目保證如果有答案的話至少有兩個合法排列,所以我們不用考慮n=12n=1或2的情況,直接看n3n\ge 3的。

首先,如果nn放在排列中間,那麼肯定會有兩個一樣的前綴和,所以nn一定要放在開頭。

nn爲奇數時,由於nn一定在第一個,i=1ni0mod  n\sum_{i=1}^ni\equiv0\mod n所以後面一定有兩個重複的數,輸出1-1

那麼只剩nn爲偶數的情況,爲了讓模意義下的前綴和不重不漏,不妨將數兩兩分爲一組,使每一組和爲n+1n+1
n,(n1,2),(n3,4), ,1n,(n-1,2),(n-3,4),\cdots,1

第二組的話,我們可以讓每組的數字和爲n1n-1
n,(1,n2),(3,n4), ,n1n,(1,n-2),(3,n-4),\cdots,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();}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章