JZOJ 100024. 【NOIP2016提高A组模拟7.6】数球
Description
小A有n個球,編號分別為1到n,小A每次都會從n個球中取出若干個球,至少取一個,至多取n個,每次取完再放回去,需要滿足以下兩個條件。
每次取出的球的個數兩兩不同。
每次取出的球的集合兩兩不包含。包含是指,對于兩次取球,對于取的數目少的那次取球的所有球都出現在取的數目多的那次取球中,例如{1,2}和{1,2,4},{1,2}和{2,3}則不算作包含。
而小A現在突然想知道他最多能進行多少次這樣的操作,并希望你能給出具體的取球方案。
Input
一個整數n。
Output
第一行一個數k,表示能進行的最多次數。
接下來k行,每行第一個整數p,表示這次取的球數,接下來p個數表示這次取的球的編號,編號只需要不同,不需要按照順序輸出,本題設有spj。
對于每個測試點,每組數據第一行正確可以獲得20%的分,如果第一行和方案均正確獲得100%的分。
Sample Input
4
Sample Output
2
1 1
2 3 4
Data Constraint
對于30%的數據,n<=7。
對于50%的數據,n<=20。
對于70%的數據,n<=100。
對于100%的數據,4<=n<=1000。
Solution
這題我們可以采用構造法,構造出合法的取球方案。
顯然,答案必為 N?2 (1~N-2 的取球方案)。
事實上我們可以兩個兩個跳著處理,假設我們已經得出了 1 到 N-2 的答案,要求 N 的答案。
那么就有原答案的長度為 1~N-4 ,可填的兩個數分別是 N 和 N-1
為了避免“包含”,我們在每行末尾都加上一個 N 。
那這樣答案就的長度就變成了 2~N-3 ,之后 1 的位置就填上 N-1 。
最后一行填 1~N-2 ,這樣顯然是不會出現“包含”情況的。(不懂可以找數嘗試)
那么這樣時間復雜度就是 O(N2) 。
Code
#include<cstdio> using namespace std; const int N=1000; int n,num; int f[N*2][N]; inline void write(int x) {if(x>9) write(x/10);putchar(x%10+'0'); } int main() {scanf("%d",&n);write(n-2),putchar('\n');f[num=N][0]=f[N][1]=1;if(n&1)for(int i=5;i<=n;i+=2){num--;f[num][f[num][0]=1]=i-1;for(int j=num+1;j<=num+i-4;j++) f[j][++f[j][0]]=i;for(int j=1;j<=i-2;j++) f[num+i-3][j]=j;f[num+i-3][0]=i-2;}else{f[num+1][0]=2;f[num+1][1]=2,f[num+1][2]=3;for(int i=6;i<=n;i+=2){num--;f[num][f[num][0]=1]=i-1;for(int j=num+1;j<=num+i-4;j++) f[j][++f[j][0]]=i;for(int j=1;j<=i-2;j++) f[num+i-3][j]=j;f[num+i-3][0]=i-2;}}for(int i=num;i<num+n-2;i++){write(f[i][0]);for(int j=1;j<=f[i][0];j++) putchar(' '),write(f[i][j]);putchar('\n');} }總結
以上是生活随笔為你收集整理的JZOJ 100024. 【NOIP2016提高A组模拟7.6】数球的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JZOJ 4307. 【NOIP2015
- 下一篇: JZOJ 100026. 【NOIP20