转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
Cake
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1517 Accepted Submission(s): 233
Special Judge
Note that you cannot divide a whole cake into small pieces that is each cake must be complete in the m parts. Each cake must belong to exact one of m parts.
The first contains two integers n and m (1≤n≤105,2≤m≤10), the number of cakes and the number of soda.
It is guaranteed that the total number of soda in the input doesn’t exceed 1000000. The number of test cases in the input doesn’t exceed 1000.
If it is possible, then output m lines denoting the m parts. The first number si of i-th line is the number of cakes in i-th part. Then si numbers follow denoting the size of cakes in i-th part. If there are multiple solutions, print any of them.
其实这题还是不容易过的,比赛的时候一看居然都过了100人了,而且发现直接贪心是不对的,于是乎乱搞了一发。。。结果居然过了。。。
这题首先只有在不能整除以及n<2m-1的时候才是NO,其余情况都是YES
然后在[2m-1,4m-2]的范围内贪心,然后之后,每2m个相互构一组
/**
* code generated by JHelper
* More info: https://github.com/AlexeyDmitriev/JHelper
* @author xyiyy @https://github.com/xyiyy
*/ #include <iostream>
#include <fstream> //#####################
//Author:fraud
//Blog: http://www.cnblogs.com/fraud/
//#####################
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <sstream>
#include <ios>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <vector>
#include <string>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <climits>
#include <cctype> using namespace std;
#define pb(X) push_back(X)
#define rep(X, N) for(int X=0;X<N;X++)
#define rep2(X, L, R) for(int X=L;X<=R;X++)
typedef long long ll; #define gao() out<<"NO"<<endl
vector<int> ans[];
int used[];
ll tot; class hdu5355 {
public:
int ave; void solve(std::istream &in, std::ostream &out) {
int n, m;
in >> n >> m;
tot = (ll) (n + ) * n / ;
if (tot % m != ) {
gao();
return;
}
int tmp = tot / m;
if (n < * m - ) {
gao();
return;
}
int num = n / m;
if (tmp == n) {
out << "YES" << endl;
out << << " " << n << endl;
rep(i, m - ) {
out << << " " << i + << " " << n - i - << endl;
}
return;
}
if (m == ) {
out << "YES" << endl;
out << n;
rep2(i, , n)out << " " << i;
out << endl;
return;
}
rep2(i, , m)ans[i].clear();
int f = n;
int c = ;
/*while(n>=4*m-1){
rep2(i,1,m){
if(c&1) ans[i].pb(f - i + 1);
else ans[i].pb(f - m + i);
}
f -= m;
n -= m;
c++;
rep2(i,1,m){
if(c&1) ans[i].pb(f - i + 1);
else ans[i].pb(f - m + i);
}
f -= m;
n -= m;
c++;
}*/
c = (n + - m * ) % (m * ) + m * - ;
int d = (n - c) / ( * m);
for (int i = , j = c + ; i <= m; i++) {
rep(k, d)ans[i].pb(j++), ans[i].pb(n--);
}
tot = n;
n = c;
ave = (ll) ( + n) * n / / m;
set<int> s;
rep2(i, , n)s.insert(i);
rep2(i, , m) {
rep(j, ave) {
auto it = s.upper_bound(ave - j);
ans[i].pb(*--it);
j += *it;
s.erase(it);
j--;
}
} // clr(used,0);
// rep(i,tot)a[i] = n - i;
// if(dfs(0,0,n,1)){
//if(dfs(m,n,0,0,n)){
out << "YES" << endl;
// rep2(i,1,n)ans[used[i]].pb(i);
rep2(i, , m) {
int sz = ans[i].size();
out << sz;
rep(j, sz) {
out << " " << ans[i][j];
}
out << endl;
}
//}else out<<"NO"<<endl;
/*if(n % m != 0){
gao();
return;
}
if(num&1){
if(m&1){
out<<"YES"<<endl;
run(m);
rep2(i,1,m){
out<<num;
rep(j,ans[i].size()){
out<<" "<<ans[i][j];
}
int last = 3 * m + i;
int f = 4 * m;
rep2(j,4,num){
out<<" "<<last;
f += m;
if(j&1)last = f- m + i;
else last = f - i + 1;
}
out<<endl;
} }else{
gao();
return;
}
}else{
out<<"YES"<<endl;
rep2(i,1,m){
out<<num;
int last = i;
int f = m;
rep(j,num){
out<<" "<<last;
f += m;
if(j&1)last = f-i+1;
else last = f - m + i;
}
}
}*/ } bool dfs(int num, int now, int u, int m) {
if (now == ) {
int i = tot;
while (used[i])i--;
used[i] = m;
if (dfs(num + , i, i - , m))return ;
used[i] = ;
return ;
}
if (now == ave) {
if (num == tot)return ;
else return dfs(num, , tot, m + );
}
for (int i = u; i > ; i--) {
if (!used[i] && now + i <= ave) {
used[i] = m;
if (dfs(num + , now + i, i - , m))return ;
used[i] = ;
}
}
return false;
} bool dfs(int m, int n, int tot, int num, int now) {
if (!m) {
return ;
}
if (tot = ave) {
if (dfs(m - , n, , num, ))return ;
}
if (tot == ) {
int i = n;
while (used[i])i--;
used[i] = m;
if (dfs(m, n, tot + i, num + , i))return ;
used[i] = ;
return ;
}
for (int i = now; i > ; i--) {
if (!used[i] && tot + i <= ave) {
used[i] = m;
if (dfs(m, n, tot + i, num + , i - ))return ;
used[i] = ;
}
}
return false;
} }; int main() {
std::ios::sync_with_stdio(false);
std::cin.tie();
hdu5355 solver;
std::istream &in(std::cin);
std::ostream &out(std::cout);
int n;
in >> n;
for (int i = ; i < n; ++i) {
solver.solve(in, out);
} return ;
}