HDOJ5355 Cake 构造

直接贪心的做法是不对的(例如: 23 6 , 27 7 , 28 7, 31 8 等...)

多校的时候因为SPJ的问题很多WA的程序都过了,实际上这题并没有那么水......

无解的有两种情况 1: sum不能被m整除 2: sum/m比n小

剩下的情况都有解:

标程的做法是根据: n(n+1)/(2*m) 每一组里都有k对组合,如第一行中的(11 100) (12 99) (13 98)....

因为有m行所以这样的组合有2*k*m个,这些对都可以凑成一样的大小

剩下的为粉红色的部分, 这些数字有(n-(2*m-1))%(2*m)+(2*m-1)个 (如样例  1~10),然后对这部分进行从大到小的贪心.....(感觉还是有问题???....)

n=100,m=5的数据

100 5

YES

20  10  1  11  100  12  99  13  98  14  97  15
 96  16  95  17  94  18  93  19  92

20    9  2  20    91  21  90  22  89  23  88  24
 87  25  86  26  85  27  84  28  83

20    8  3  29    82  30
 81  31  80  32  79  33  78  34  77  35  76
 36  75  37  74

20    7  4  38    73  39
 72  40  71  41  70  42  69  43  68  44  67
 45  66  46  65

20    6  5  47    64  48
 63  49  62  50  61  51  60  52  59  53  58  54  57  55  56

参考题解: http://blog.csdn.net/queuelovestack/article/details/47321211

Cake

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Total Submission(s): 1347    Accepted Submission(s): 197

Special Judge

Problem Description

There are m soda
and today is their birthday. The 1-st
soda has prepared n cakes
with size 1,2,…,n.
Now 1-st
soda wants to divide the cakes into m parts
so that the total size of each part is equal.

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.

Input

There are multiple test cases. The first line of input contains an integer T,
indicating the number of test cases. For each test case:

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.

Output

For each test case, output "YES" (without the quotes) if it is possible, otherwise output "NO" in the first line.

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.

Sample Input

4
1 2
5 3
5 2
9 3

Sample Output

NO
YES
1 5
2 1 4
2 2 3
NO
YES
3 1 5 9
3 2 6 7
3 3 4 8

Source

2015 Multi-University Training Contest 6

ac的代码:

/* ***********************************************
Author        :CKboss
Created Time  :2015年08月07日 星期五 14时23分36秒
File Name     :HDOJ5355_2.cpp
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;

typedef long long int LL;

LL n,m;
vector<int> vi[10];
set<int> v;

void init()
{
	for(int i=0;i<10;i++) vi[i].clear();
}

int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);

	int T_T;
	scanf("%d",&T_T);

	while(T_T--)
	{
		cin>>n>>m;
		init();
		LL sum=n*(n+1)/2;
		if(sum%m||n+1<2*m)
		{
			puts("NO"); continue;
		}

		LL c=(n-m*2+1)%(m*2)+m*2-1;  

		v.clear();
		for(int i=1;i<=c;i++)
		{
			v.insert(i);
		}

		LL s=c*(c+1)/(m*2);

		for(int i=0;i<m;i++)
		{
			set<int>::iterator it;
			LL ts=0;
			while(ts<s)
			{
				it=v.upper_bound(s-ts);
				LL tmp=*--it;
				vi[i].push_back(tmp);
				ts+=tmp;
				v.erase(it);
			}
		}

		int st=c+1;
		int ed=n;
		int k=(n-c)/(2*m);

		for(int i=0;i<m;i++)
		{
			for(int j=0;j<k;j++)
			{
				vi[i].push_back(st); st++;
				vi[i].push_back(ed); ed--;
			}
		}

		puts("YES");

		for(int i=0;i<m;i++)
		{
			int sz=vi[i].size();
			printf("%d",sz);
			for(int j=0;j<sz;j++)
			{
				printf(" %d",vi[i][j]);
			}
			putchar(10);
		}
	}

    return 0;
}

标程的代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int sol(){
  int n,m;
  scanf("%d%d",&n,&m);
  if(((n+1ll)*n>>1)%m!=0 || m * 2 -1 > n) return puts("NO");

  const int c=(n+1-m*2)%(m*2)+m*2-1,
    s=c*(c+1)/(m*2),
    d=(n-c)/(m*2);
  puts("YES");
  set<int> v;
  for(int i=1;i<=c;++i)v.insert(i);
  for(int j=0,l=c+1;j<m;++j,putchar('\n')){
    static int o[32],c,r;
    for(c=r=0;r<s;){
      auto it = v.upper_bound(s-r);
      r+=o[c++]=*--it;
      v.erase(it);
    }
    printf("%d",c+d*2);
    for(int i=0;i<c;++i)printf(" %d",o[i]);
    for(int i=0;i<d;++i)printf(" %d %d",l++,n--);
  }
}
int main(){
  int T;
  for(scanf("%d",&T);T--;sol());
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-29 05:56:26

HDOJ5355 Cake 构造的相关文章

hdu5355 Cake(构造)

转载请注明出处: 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): 233Special Judge Problem Description There are m

hdu 5535 Cake 构造+记忆化搜索

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5355 题意:给定n与m,其中1<= n <= 1e5,2 <= m <= 10;问是否存在将1~n个数分成m组,使得每组的和相等:若存在输出m行,每行表示一组的值,否则输出NO; ps:总共T<=1000组数据,还是挺大的: 思路:预判之后,若可能存在则直接以2m为周期,从大往小构造出和相等的m组,这样就可以将n的值缩小到2m~4m-2:因为当n = 4m-1时,再次减去一个周期,下

HDU 5355 Cake (WA后AC代码,具体解析,构造题)

题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=5355 题面: Cake Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1632    Accepted Submission(s): 273 Special Judge Problem Description There are s

HDU 5355 Cake (WA后AC代码,详细解析,构造题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5355 题面: Cake Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1632    Accepted Submission(s): 273 Special Judge Problem Description There are m

hdu 5355 Cake(构造+回溯)

题意: 给出一个蛋糕,切成1~n大小的n块,问能否在不继续切割的情况下拼凑出m等份. 解析: 首先可以求出这些蛋糕的总和n?(n+1)/2,如果总和sum%m != 0那么就不肯能被平分成m份,那么输出"NO". 接下来计算平均数avg=sum/m,如果平均数avg < n的话,蛋糕是不可能用完的,同样也输出"NO". 剩下的情况蛋糕是一定能拼成"YES"的,那么可以将这些蛋糕以2*m为单位一组一组的分配,每个人拿当前这组的最大和最小,次大

Java的结构之美【1】——构造对象

当我们遇到多个构造器参数的时候可能会想到用构件器,代码如下: /** * 构建器 * @author 阳光小强 * */ public class Lunch { private String cake; private String meat; private String milk; private String drink; public Lunch(){ this(null); } public Lunch(String meat){ this(null, meat, null); }

poj 2515 Birthday Cake

1 /** 2 大意 : 求1^m + 2^m + 3^m + 4^m +....+ n^m 3 解题步骤: 4 先构造从0到m的第1阶差分序列,然后以下所有2---->p阶的差分表. 5 令C[n+1][1]=n,用递推构造C[n+1][1]~C[n+1][p+1]的组合数打个一维表: 6 最后利用C0*C[1]+C1*C[2]+...+Cp*C[p+1]得出答案... 7 注意: java 提交时,一定要将包名去掉,,并且类名为Main 8 这一题就是因为多加了个包名,,一直是 runtim

CodeForces 404C Restore Graph (构造)

题意:让人构造一个图,满足每个结点边的数目不超过 k,然后给出每个结点到某个结点的最短距离. 析:很容易看出来如果可能的话,树是一定满足条件的,只要从头开始构造这棵树就好,中途超了int...找了好久. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include

[.net]基元线程同步构造

1 /* 基元线程同步构造 2 用户模式构造: 3 易变构造(Volatile Construct) 4 互锁构造(Interlocked Construct):自旋锁(Spinlock) 乐观锁(Optimistic Concurrency Control,乐观并发控制) 5 内核模式构造: 6 事件构造(Event) 7 信号量构造(Semaphore) 8 互斥体构造(Mutex) 9 */ 10 11 //易变构造,Volatile.Write()之前的所有字段写入操作,必须再该方法调用