Divide the Stones(HDU-6616)

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

题意:t 组数据,每组给出 n、k 两个数,代表有 n 个重量从 1~n 的石头,现在要将这些石头分成 k 堆,使得每堆的重量与数量相等,问能否分配,若能,输出 yes 与对应方案,若不能则输出 no,题目保证 k 是 n 的约数

思路:

首先,对于 1 到 n 的和 \frac{n(n+1)}{2} 如果不能整除 k,那么一定不能分配

然后再考虑 \frac{n}{k},当其为偶数时,每一堆的个数为偶数,重量为 \frac{\frac{n(n+1)}{2}}{k},那么可以用 \frac{\frac{n}{k}}{2} 个和为 n+1 的数对组成

当其为奇数时,我们将前 3k 个石头分成等重量与等数量的 k 堆,即每堆 3 个,重量为 \frac{9k+3}{2},之后再将剩下的 n-3k 个石头成对进行分配

而将前 3k 个石头分成 k 堆,分法有多种,比较简单的一种是:

  • 若 i 为奇数:i,\frac{3k+2}{2}-\frac{i}{2},\frac{6k+1}{2}-\frac{i}{2}
  • 若 i 为偶数:i,\frac{4k+2}{2}-\frac{i}{2},\frac{5k+1}{2}-\frac{i}{2}

Source Program

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<unordered_map>
#include<bitset>
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
#define Pair pair<int,int>
LL quickPow(LL a,LL b){ LL res=1; while(b){if(b&1)res*=a; a*=a; b>>=1;} return res; }
LL multMod(LL a,LL b,LL mod){ a%=mod; b%=mod; LL res=0; while(b){if(b&1)res=(res+a)%mod; a=(a<<=1)%mod; b>>=1; } return res%mod;}
LL quickPowMod(LL a, LL b,LL mod){ LL res=1,k=a; while(b){if((b&1))res=multMod(res,k,mod)%mod; k=multMod(k,k,mod)%mod; b>>=1;} return res%mod;}
LL getInv(LL a,LL mod){ return quickPowMod(a,mod-2,mod); }
LL GCD(LL x,LL y){ return !y?x:GCD(y,x%y); }
LL LCM(LL x,LL y){ return x/GCD(x,y)*y; }
const double EPS = 1E-10;
const int MOD = 998244353;
const int N = 200000+5;
const int dx[] = {-1,1,0,0,1,-1,1,1};
const int dy[] = {0,0,-1,1,-1,1,-1,1};
using namespace std;

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        int n, k;
        scanf("%d%d", &n, &k);
        LL sum = 1LL * n * (n + 1) / 2;
        if (sum % k != 0)
            printf("no\n");
        else {
            printf("yes\n");
            if (k == 1) { // k=1时特判
                for (int i = 1; i <= n; i++)
                    printf("%d ", i);
                printf("\n");
            } else {
                if ((n / k) % 2 == 0) { // n/k为偶数
                    int temp = k;
                    int i = 1;
                    while (temp--) {
                        for (int j = 1; j <= n / k / 2; j++)
                            printf("%d %d ", i++, n + 1 - i);
                        printf("\n");
                    }
                } else { // n/k为奇数
                    int i = 1, j = 3 * k + 1, temp = k;
                    while (temp--) {
                        //前k堆
                        if (i % 2)
                            printf("%d %d %d ", i++, (3 * k + 1) / 2 - i / 2, (6 * k + 1) / 2 - i / 2);
                        else
                            printf("%d %d %d ", i++, (4 * k + 2) / 2 - i / 2, (5 * k + 1) / 2 - i / 2);
                        //剩余的n-3k个
                        for (int i = 1; i <= (n / k - 3) / 2; i++)
                            printf("%d %d ", j++, 3 * k + 1 + n - j);
                        printf("\n");
                    }
                }
            }
        }
    }
    return 0;
}
发布了1871 篇原创文章 · 获赞 702 · 访问量 194万+

猜你喜欢

转载自blog.csdn.net/u011815404/article/details/102304897