👉传送门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 }