HDU - 6616 Divide the Stones

Divide the Stones

👉传送门php

Time Limit: 6000/3000 MS (Java/Others)c++

Memory Limit: 131072/131072 K (Java/Others)ide

Problem Description

There are n stones numbered from 1 to n.
The weight of the i-th stone is i kilograms. We divide the stones into k groups.
Each group consists of exactly stones.
We define the weight of each group is sum of the stones’ weights in the group.
Can we divide the stones so that the weights of all groups are same?

Input

The first line of input contains an integer T (1 <= T <= 100) denoting the number of test cases.
Each test case consists of one line containing two integers n (1 ≤ n ≤ 100000), k (k is divisor of n).
It is guaranteed that the sum of n overall test cases does not exceed 500000.

Output

For each test case, if you can’t divide into k groups satisfying condition, print “no”.
Else if you can divide into k groups satisfying condition, print “yes” in one line and then print k lines.
The i-th line represent the indices of stones belonging to the i-th group.
If there are multiple solutions, you can print any of them.

Sample Input

1
4 2

Sample Output

yes 1 4
2 3

 Tips

题意

有 $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 }
View Code
相关文章
相关标签/搜索