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 2Sample Output
yes
1 4
2 3
题意:t 组数据,每组给出 n、k 两个数,代表有 n 个重量从 1~n 的石头,现在要将这些石头分成 k 堆,使得每堆的重量与数量相等,问能否分配,若能,输出 yes 与对应方案,若不能则输出 no,题目保证 k 是 n 的约数
思路:
首先,对于 1 到 n 的和 如果不能整除 k,那么一定不能分配
然后再考虑 ,当其为偶数时,每一堆的个数为偶数,重量为
,那么可以用
个和为 n+1 的数对组成
当其为奇数时,我们将前 3k 个石头分成等重量与等数量的 k 堆,即每堆 3 个,重量为 ,之后再将剩下的 n-3k 个石头成对进行分配
而将前 3k 个石头分成 k 堆,分法有多种,比较简单的一种是:
- 若 i 为奇数:
- 若 i 为偶数:
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;
}