hdu5355--Cake(构造)

题目链接:点击打开链接

题目大意:给出n块蛋糕,现在有m个人要分蛋糕,要求分的大小是一样的,并且蛋糕不能切开,问能不能分成,并输出可以分成的方法。

计算蛋糕的和sum,如果sum不能整除m,或者sum/m<n,将式子转化,得n < 2*m-1 那一定是不可以的。

同样也就得到n >= 2*m-1,就是可以的,所以可以先计算出(n-2*m+1)%(2*m)+2*m-1,先拿出2*m-1个来,那么剩下的蛋糕中,每连续2*m个都可以组成一个相同的数值(小的递增,大的递减),最终会剩下mod = (n-2*m+1)%(2*m)+2*m-1个蛋糕,可以认为这些蛋糕是从1到mod,计算剩余的和sum,和平均数ave,现在我们要做的就是把1到mod分为m份,使用set,不断组成ave,一直到分为m份。

#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <algorithm>
using namespace std ;
#define LL __int64
vector<int> vec[11] ;
set<int> s ;
set<int>::iterator iter ;
int n , m ;
int main() {
    LL sum ;
    int t , n , m , num , mod ;
    int i , j , k ;
    scanf("%d", &t) ;
    while( t-- ) {
        scanf("%d %d", &n, &m) ;
        sum = n ;
        sum = sum*(sum+1)/2 ;
        if( sum%m || n < 2*m-1) {
            printf("NO\n") ;
            continue ;
        }
        mod = (n-2*m+1)%(2*m) + 2*m-1 ;
        num = (n-mod)/(2*m) ;
        for(i = 1 ; i <= m ; i++) vec[i].clear() ;
        i = mod+1 ; j = n ;
        while( num-- ) {
            i = mod+1+(2*m)*num ;
            j = i+(2*m)-1 ;
            for(k = 1 ; k <= m ; k++) {
                vec[k].push_back(i) ;
                vec[k].push_back(j) ;
                i++ ; j-- ;
            }
        }
        sum = mod ;
        sum = sum*(sum+1)/2 ;
        sum /= m ;
        s.clear() ;
        for(i = 1 ; i <= mod ; i++)
            s.insert(i) ;
        for(i = 1 ; i <= m ; i++) {
            k = sum ;
            while( k ) {
                iter = s.upper_bound(k) ;
                iter-- ;
                //printf("%d\n", *iter) ;
                vec[i].push_back(*iter) ;
                k -= *iter ;
                s.erase(*iter) ;
            }
        }
        printf("YES\n") ;
        for(i = 1 ; i <= m ; i++) {
            num = vec[i].size() ;
            printf("%d ", num) ;
            for(j = 0 ; j < num-1 ; j++)
                printf("%d ", vec[i][j]) ;
            printf("%d\n", vec[i][j]) ;
        }
    }
    return 0 ;
}

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

时间: 2024-08-15 05:31:11

hdu5355--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

hdu5355 Cake

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 w

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时,再次减去一个周期,下

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个,这些对都可以凑成一样的大小 剩下的为粉红色的部分, 这些

递归练习1

感觉自己这方面很弱,都是看着题解做的orz.. fzu2038 Another Postman Problem(递归求解) 题意:n个点n-1条边组成无向连通图,求每个点到其他所有点的路径总和的和. 题解:每条边的访问次数为边两端点数乘积的两倍.递归遍历每个点的每条边即可. 1 #include<cstdio> 2 #include<vector> 3 #include<cstring> 4 using namespace std; 5 const int N=1e5+

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