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
相關文章
相關標籤/搜索