ACM - CF - 1498B - Box Fitting - 数据结构+二分

题目链接

题意:
n个木条,高度为1,长度都是2的次幂。问给定长度为L的方格,高度为1,最少需要多少个这样的方格可以把所有n个木条放进去?

思路:
每次放可以放的最大的!即,贪心。
难点:
比较当前格子的剩余量以及剩下木条的可用的最大值时,需要排序。排好了之后,每次放进去的木条应该是最接近剩下长度的。

举例:
在样例1中,应该放:8+8,而不是8+4+2+1.

vector<int> 可以排序,怎么解决贪心的问题:二分。
upper_bound():在有序数组中,找到用于在指定范围内查找大于目标值的第一个元素。
lower_bound():在有序数组中,找到用于在指定范围内查找不小于(大于等于)目标值的第一个元素。
问题又来了:
题目中贪心要找的是小于等于啊!
我自己的小技巧是:把正数变成负数,扔进去。正数是小于等于,那么负数就是大于等于。</int>

一开始sort之后,数组就有序了。每次找到一个就拿走一个,数组仍然有序。

代码如下:

#include<bits/stdc++.h>
using namespace std;

vector<int> a;
vector<int>::iterator it;
int T;
int n, m, x;
int ans;

int main(){
    //freopen("input.txt", "r", stdin);
    scanf("%d", &T);
    while(T--){
        if (a.size()) a.clear();
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++){
            scanf("%d", &x);
            a.push_back(x * (-1));
        }
        sort(a.begin(), a.end());
        //for(it=a.begin(); it!=a.end(); it++)
        //    cout<<*it<<" ";
        //cout << endl;
        ans = 0;
        while(a.size()){
            int Left = m * (-1);
            int flag = 0;
            while(!flag){
                it = lower_bound(a.begin(), a.end(), Left);
                if (it < a.end()){
                    Left -= (*it);
                    a.erase(it);
                }
                else{
                    flag = 1;
                }
            }
            ans++;
        }
        printf("%d\n", ans);
    }
    return 0;
}

全部评论

相关推荐

不愿透露姓名的神秘牛友
昨天 20:49
某国企 研发工程师 31W 硕士211
点赞 评论 收藏
分享
LZStarV:冲就好了,就算真的是字节也冲,面评脏了大不了等三四个月就淡了,而且等到那个时候实力进步了选择还多,何必拘泥于字节
点赞 评论 收藏
分享
10-28 17:30
已编辑
华东交通大学 Java
iori2333:这太正常了 我字节面了四五轮 没有一次是在官网投递 都是hr主动捞
秋招笔试记录
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务