多校第六场 1003 hdu 5355 Cake(贪心)

题目链接:(数据加强后wa了)

hdu 5355


题目大意:

给出一个蛋糕。切成1~n大小的n块。问是否能在不继续分割的情况下拼凑出m等份。


题目分析:

  • 首先我们是可以知道每份蛋糕的尺寸的,利用n*(n+1)/2m可以算出来,假设不能整除的话,那么一定无解。

  • 然后我们考虑怎样构造一组解,对于一块蛋糕,我想到了一个贪心策咯,尽量选择最大块的蛋糕,由于假设能选可是不选这块蛋糕,那么也一定是通过选取小块的蛋糕来拼凑出这块蛋糕的大小,可是假设小的拼凑出了这块,那么就不能用于拼凑其它的蛋糕,显然选择最大的这块是最优的,由于他不可能被用来拼凑出其它的蛋糕。所以当前选取它不会造成其它的蛋糕拼凑受影响,所以我们这样选取一定是正确的。

AC代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;
typedef long long LL;
int t;
LL n,m;
vector<int> v[20];
int mark[100007];

int main ( )
{
    scanf ( "%d" , &t );
    while ( t-- )
    {
        memset ( mark , 0 , sizeof ( mark ));
        for ( int i = 0 ; i < 20 ; i++ )
            v[i].clear();
        scanf ( "%I64d%I64d" , &n , &m );
        LL ans = n*(n+1)/2;
        LL num = ans/m;
        if ( ans%m ||  num < n )
        {
            puts ( "NO" );
            continue;
        }
        LL r = n;
        int i;
        for ( i = 0 ; i < m ; i++ )
        {
            //cout <<n << " " << num << " "<< i << " " << r << endl;
            LL temp = num;
            bool flag = true;
            while ( mark[r] && r > 1 ) r--;
            while ( temp >= r && !mark[r] )
            {
                v[i].push_back ( r );
                mark[r] = true;
                temp -= r;
                r--;
                if ( r == 0 ) break;
                while ( mark[r] && r > 1 ) r--;
            }
            if ( temp == 0 )
            {
                flag = false;
            }
            else if ( !mark[temp] )
            {
                v[i].push_back ( temp );
                mark[temp] = true;
                flag = false;
            }
            else
            {
                while ( true )
                {
                    bool finish = false;
                    for ( int j = temp ; j > 0 ; j-- )
                    {
                        if ( !mark[j])
                        {
                            mark[j] = true;
                            v[i].push_back ( j );
                            temp -= j;
                            finish = true;
                            break;
                        }
                    }
                    if ( !finish ) break;
                    if ( temp == 0 )
                    {
                        flag = false;
                        break;
                    }
                }
            }
            if ( flag ) break;
        }
        if ( i == m )
        {
            puts ( "YES" );
            for ( int i = 0 ; i < m ; i++ )
            {
                printf ( "%d" , v[i].size() );
                for ( int j = 0 ; j < v[i].size() ; j++ )
                    printf ( " %d" , v[i][j] );
                puts ( "");
            }
        }
        else puts ( "NO" );
    }
}
时间: 2024-10-19 20:49:47

多校第六场 1003 hdu 5355 Cake(贪心)的相关文章

【HDU】4923 Room and Moor(2014多校第六场1003)

Room and Moor Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 263    Accepted Submission(s): 73 Problem Description PM Room defines a sequence A = {A1, A2,..., AN}, each of which is either 0

2014多校第六场 1005 || HDU 4925 Apple Tree

题目链接 题意 : 给你一块n×m的矩阵,每一个格子可以施肥或者是种苹果,种一颗苹果可以得到一个苹果,但是如果你在一个格子上施了肥,那么所有与该格子相邻(指上下左右)的有苹果树的地方最后得到的苹果是两倍,如果(i,j)有一颗苹果树,(i-1,j)与(i,j+1)施了肥,那么苹果应该是1的两倍2,2的两倍4,最后是4个苹果,问你怎么安排苹果和施肥的格子使最后得到的苹果最多. 思路 : 画了图就可以看出来,苹果和苹果,肥与肥之间不要相邻就好了,所有的苹果之间都有施肥,所有施肥的格子都被苹果隔开了才能

2014多校第六场 1010 || HDU 4930 Fighting the Landlords (模拟)

题目链接 题意 : 玩斗地主,出一把,只要你这一把对方要不了或者你出这一把之后手里没牌了就算你赢. 思路 : 一开始看了第一段以为要出很多次,实际上只问了第一次你能不能赢或者能不能把牌出尽. 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 5 using namespace std ; 6 7 char str1[20],str2[20] ; 8 int hash1[20],hash2[2

2014多校第七场1003 || HDU 4937 Lucky Number

题目链接 题意 : 给定一个十进制n,让你转化成某个进制的数,让这个数只包含3 4 5 6这些数字,这个进制就成为n的幸运数字,输出有多少幸运数字,例如19,5进制表示是34,所以5是19的一个幸运数. 思路 : 以下思路有这里提供 先考虑特殊情况,所情况下会有无穷个?只有n=3,4,5,6的时候,因为这几个数在大于n的进制下都是他本身..注意特殊情况不包括33,343这些(我一开始就死在这里了,wa了三次).因为33在34进制下就不是33了(类似于10在16进制下就是A了). 我们知道n=a0

HDU 5794 A Simple Nim 2016多校第六场1003

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5795 题意:给你n堆石子,每一堆有ai石头,每次有两种操作,第一种在任意一堆取出任意数量的石头但不能为0,第二种把一堆石头分成三堆任意数量的石头(不能为0),问是先手赢还是后手赢. 题解:这就是一个Nim游戏!那么Nim游戏一般跟SG函数有关,所以这道题打表找规律即可. 关于SG函数,在这里也说一下吧!毕竟第一次接触. Nim游戏与SG函数:http://baike.baidu.com/link?u

多校第六场 HDU 4927 JAVA大数类

题目大意:给定一个长度为n的序列a,每次生成一个新的序列,长度为n-1,新序列b中bi=ai+1?ai,直到序列长度为1.输出最后的数. 思路:这题实在是太晕了,比赛的时候搞了四个小时,从T到WA,唉--对算组合还是不太了解啊,现在对组合算比较什么了-- import java.io.*; import java.math.*; import java.util.*; public class Main { public static void main(String[] args) { Sca

HDU 4923 Room and Moor (多校第六场C题) 单调栈

Problem Description PM Room defines a sequence A = {A1, A2,..., AN}, each of which is either 0 or 1. In order to beat him, programmer Moor has to construct another sequence B = {B1, B2,... , BN} of the same length, which satisfies that: Input The inp

2014多校第六场 || HDU 4927 Series 1(杨辉三角组合数)

题目链接 题意 : n个数,每操作一次就变成n-1个数,最后变成一个数,输出这个数,操作是指后一个数减前一个数得到的数写下来. 思路 : 找出几个数,算得时候先不要算出来,用式子代替,例如: 1 2 3 4 5 6 (2-1) (3-2) (4-3) (5-4)(6-5) (3-2-2+1)(4-3-3+2)(5-4-4+3)(6-5-5+4) (4-3-3+2-3+2+2-1)(5-4-4+3-4+3+3-2)(6-5-5+4-5+4+4-3) (5-4-4+3-4+3+3-2-4+3+3-2

2014 HDU多校弟六场J题 【模拟斗地主】

这是一道5Y的题目 有坑的地方我已在代码中注释好了 QAQ Ps:模拟题还是练的太少了,速度不够快诶 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #include <iostream> #include <climits> #include <cstring> #include <cmath> #inclu