👉傳送門php
Time Limit: 6000/3000 MS (Java/Others)c++
Memory Limit: 131072/131072 K (Java/Others)ide
1 4 2
yes 1 4 2 3
有 $n$ 顆石子,第 $i$ 顆重量爲 $i$ 。如今請你將這 $n$ 顆石子均分紅 $k$ 堆,每堆的重量和石子數量都同樣。輸出任意一種均分方式,若是不能夠,輸出 no 。spa
首先來講,當 $k \nmid n(n+1)/2$ 時必定無解。code
而後咱們先考慮 $n/k$ 爲偶數時的情形。blog
此時,每一堆個數爲偶數,重量爲 $(n+1)n/k/2$ ,則能夠用 $n/k/2$ 個和爲 $n+1$ 的數對組成。ip
而後考慮 $n/k$ 爲奇數的狀況。get
此時,咱們能夠先將前 $3k$ 顆石子按照同等重量和數量分紅 $k$ 堆,即每堆 $3$ 個,重量 $(9k+3)/2$ 。input
而後,咱們只需將剩下的部分紅對分配便可。it
關於 $3k$ 分紅 $k$ 堆的方式,可能分法有多種,下面給出一種比較容易想到的:
若 $i$ 是奇數,則分爲 $$i,\frac{3k+2}{2}-\frac{i}{2},\frac{6k+1}{2}-\frac{i}{2}$$
不然,分爲 $$i,\frac{4k+2}{2}-\frac{i}{2},\frac{5k+1}{2}-\frac{i}{2}$$
1 #include <bits/stdc++.h> 2 using namespace std; 3 int T,n,k; 4 int main(){ 5 scanf("%d",&T); 6 while (T--){ 7 scanf("%d%d",&n,&k); 8 if (1LL*n*(n+1)/2%k){ 9 puts("no"); 10 } 11 else{ 12 puts("yes"); 13 if (k==1){ 14 putchar('1'); 15 for (int i=2;i<=n;++i) 16 printf(" %d",i); 17 puts(""); 18 } 19 else if ((n/k)&1){ 20 int i=1,j=3*k+1,kk=k; 21 while (kk--){ 22 if (i&1) 23 printf("%d %d %d", 24 i++,(3*k+1)/2-i/2,(6*k+1)/2-i/2); 25 else 26 printf("%d %d %d", 27 i++,(4*k+2)/2-i/2,(5*k+1)/2-i/2); 28 for (int i=0;i<(n/k-3)/2;++i) 29 printf(" %d %d",j++,3*k+1+n-j); 30 puts(""); 31 } 32 } 33 else{ 34 int i=1,kk=k; 35 while (kk--){ 36 printf("%d %d",i++,n+1-i); 37 for (int j=1;j<n/k/2;++j) 38 printf(" %d %d",i++,n+1-i); 39 puts(""); 40 } 41 } 42 } 43 } 44 return 0; 45 }