• HDOJ 5355 Cake 【set 数论】


    HDOJ 5355 Cake 【set math】

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5355


    这个题…真的wa好多次啊…
    并且对算法要求很苛刻,稍不留神就会超时
    分析可以见这篇文章
    http://blog.csdn.net/queuelovestack/article/details/47321211
    思路就是把1~n个数分成两份
    并且使 使用二分搜索判断的部分尽可能小 另一部分直接匹配进入分组
    然后计算化简公式即可
    具体可以看我的代码的注释部分,还算比较详细


    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<set>
    using namespace std;
    typedef long long ll;
    int T, n, m;
    ll sum;
    int div1, div2;
    ll divSum;
    ll divAve;
    int divCake[15][100005];
    int k;
    set<int> cake;
    set<int> :: iterator it;
    
    void Resolve(){
        cake.clear();
        memset(divCake, 0, sizeof(divCake));
        sum = (1+n)*1LL*n / 2;
        if((sum % m != 0) || (n < (2*m-1))){ // sum / m ≥ n 时才有解,结合sum的求解公式化简得 n ≥ 2m-1
            puts("NO");
            return;
        }
        else{
            printf("YES
    ");
            //如果可以分成m组, 可以将1~n分成两组,
            //第二组div2的个数为k*2*m (k = 0, 1, ...)
            //那么n~(n-div2+1)这div2个数据就可以一个最大数配一个最小数分成m组和一致的数据
            //同时, 剩余的第一组div1也要能均分成m分, 根据开始求出的公式 n ≥ 2m-1, 故div1至少要有2*m-1个数据才可以均分
            div1 = ((n-(2*m-1)) % (2*m)) +(2*m-1); // m ≤ 10  故div1至多为40 规模极小
            div2 = n - div1;
            k = div2 / (2*m);
            //printf("div1: %d div2: %d k: %d 
    ", div1, div2, k);
            divSum = (div1+1)*1LL*div1 / 2;
            divAve = divSum / m;
            for(int i = 1; i <= div1; i++) cake.insert(i);
            for(int i = 0; i < m; i++){ // 分前div1个蛋糕
                int tempAve = divAve;
                int pos = 0;
                while(tempAve > 0){
                    it = cake.upper_bound(tempAve);
                    //upper_bound(x) 若x存在, 返回有序数组中最后一个值为x的元素的下一个位置
                    //若x不存在, 返回x应该存在的位置, 即小于x的元素中最大的那个元素的下一个位置
                    pos++;
                    divCake[i][pos] = *--it;
                    tempAve -= *it;
                    divCake[i][0] = pos;
                    cake.erase(it);
                }
            }
            int posL = div1+1, posR = n;
            for(int i = 0; i < m; i ++){
                printf("%d", divCake[i][0]+2*k);
                for(int j = divCake[i][0]; j > 0; j--){
                    printf(" %d", divCake[i][j]);
                }
                for(int l = k; l > 0; l--){
                    printf(" %d %d", posL++, posR--);
                }
                printf("
    ");
            }
            return;
        }
    }
    
    int main(){
        scanf("%d", &T);
        while(T--){
            scanf("%d%d", &n, &m);
            Resolve();
        }
        return 0;
    }
    

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

  • 相关阅读:
    php内存管理机制、垃圾回收机制
    Redis 3.2.1集群搭建
    centos开启IPV6配置方法
    /etc/hosts.allow和/etc/hosts.deny详解
    3元购买微信小程序解决方案一个月
    linux下使用ntfs-3g挂载NTFS出错
    腾讯云微信小程序域名变更指南
    nginx开启gzip压缩
    centos 7使用yum安装docker容器
    linux中启动网卡报错:Bringing up interface eth1: Error: Connection activation failed
  • 原文地址:https://www.cnblogs.com/miaowTracy/p/4836764.html
Copyright © 2020-2023  润新知