其他分享
首页 > 其他分享> > Vjudge题目杂集(1)

Vjudge题目杂集(1)

作者:互联网

贪心的一些趣题

 

A - 书架

题目描述:

蒜头君最近买了一个书架用来存放奶牛养殖书籍,但书架很快被存满了,只剩最顶层有空余。
蒜头君共有 NN 头奶牛 (1 <= N <= 20,000)(1≤N≤20,000),每头奶牛有自己的高度 H_i(1 <= Hi <= 10,000)H 
i(1≤Hi≤10,000),NN 头奶牛的总高度为 SS。书架高度为 B(1 <= B <= S < 2,000,000,007)B(1≤B≤S<2,000,000,007).
为了到达书架顶层,奶牛可以踩着其他奶牛的背,像叠罗汉一样,直到他们的总高度不低于书架高度。当然若奶牛越多则危险性越大。为了帮助John到达书架顶层,找出使用奶牛数目最少的解决方案吧。

输入格式

第 1 行:空格隔开的整数 N 和 B;

第 2 ~ N+1 行:第 i+1 行为整数 Hi​。

输出格式

能达到书架高度所使用奶牛的最少数目。

示例:

输入:
6 40
6
18
11
13
19
11
输出: 3

 

这道题思路的话,就是简单的贪心。计算最少符合数目,即从大到小排序,遍历高度值。

 

代码:

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

void answer(){
    int N, B;
    cin >> N >> B;
    vector<int> height(N);
    for(int i = 0; i < N; i++){
        cin >> height[i];
    }
    sort(height.begin(), height.end());
    reverse(height.begin(), height.end());
    int begin = 0, sum = 0,res = 0;
    while(true){
        sum += height[begin];
        begin++;
        res++;
        if(sum >= B){
            break;
        }
    }
    cout << res;
}

int main() {
    answer();
}

 

 

B - 花生采摘

题目描述:

鲁宾逊先生有一只宠物猴,名叫多多。这天,他们两个正沿着乡间小路散步,突然发现路边的告示牌上贴着一张小小的纸条:“欢迎免费品尝我种的花生!——熊字”。

鲁宾逊先生和多多都很开心,因为花生正是他们的最爱。在告示牌背后,路边真的有一块花生田,花生植株整齐地排列成矩形网格(如图 11)。有经验的多多一眼就能看出,每棵花生植株下的花生有多少。为了训练多多的算术,鲁宾逊先生说:“你先找出花生最多的植株,去采摘它的花生;然后再找出剩下的植株里花生最多的,去采摘它的花生;依此类推,不过你一定要在我限定的时间内回到路边。”

我们假定多多在每个单位时间内,可以做下列四件事情中的一件:

1) 从路边跳到最靠近路边(即第一行)的某棵花生植株;

2) 从一棵植株跳到前后左右与之相邻的另一棵植株;

3) 采摘一棵植株下的花生;

4) 从最靠近路边(即第一行)的某棵花生植株跳回路边。

现在给定一块花生田的大小和花生的分布,请问在限定时间内,多多最多可以采到多少个花生?注意可能只有部分植株下面长有花生,假设这些植株下的花生个数各不相同。

例如在图2所示的花生田里,只有位于(2, 5),(3, 7),(4, 2),(5, 4) 的植株下长有花生,个数分别为 13, 7, 15, 9。沿着图示的路线,多多在 21 个单位时间内,最多可以采到 37 个花生。

输入格式

输入第一行包括三个整数,M, N 和 K,用空格隔开;表示花生田的大小为 M×N(1≤M,N≤20),多多采花生的限定时间为 K(0≤K≤1000)个单位时间。

接下来的 M 行,每行包括 N 个非负整数,也用空格隔开;第i+1 行的第 j 个整数 Pij​(0≤Pij​≤500)表示花生田里植株 (i,j) 下花生的数目,0 表示该植株下没有花生。

输出格式

包括一行,这一行只包含一个整数,即在限定时间内,多多最多可以采到花生的个数。

示例:

输入:
6 7 21
0 0 0 0 0 0 0
0 0 0 0 13 0 0
0 0 0 0 0 0 7
0 15 0 0 0 0 0
0 0 0 9 0 0 0
0 0 0 0 0 0 0

输出: 37

 

本题看起来是求最优解 实则还是贪心求解。计算最多采取花生数目,升序排序每个位置花生的数目和横纵坐标。

在每一次采取前需计算是否可以回到路上。需要注意的是:在第一次进入时要特殊处理,即直接找最大值。

随后每次时间花费均为 abs(map_message[i-1].x - map_message[i].x) + abs(map_message[i-1].y - map_message[i].y) + 1

 

代码:

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

struct search_map{
    int x, y, num;
}; 
search_map map_message[401];

int bigger(search_map x, search_map y){
    return x.num > y.num;
}
int answer(){
    int M, N, K, p = 0, res = 0;
    cin >> M >> N >> K;
    vector<vector<int>> map(M, vector<int>(N));
    for(int i = 0; i < M; i++){
        for(int j = 0; j < N; j++){
            cin >> map[i][j];
            if(map[i][j] != 0){
                map_message[p].x = j + 1;
                map_message[p].y = i + 1;
                map_message[p].num = map[i][j];
                p++;
            }
        }
    }
    sort(map_message, map_message + p, bigger);
    for(int i = 0; i < p; i++){
        if(!i){
            K -= (map_message[i].y + 1);
        }
        else K -= (abs(map_message[i-1].x - map_message[i].x) + abs(map_message[i-1].y - map_message[i].y) + 1);
        if(K >= map_message[i].y){
            res += map_message[i].num;
        }
        else break;
    }
    return res;
}

int main() {
    int ans = answer();
    cout << ans;
}

 

C - 纪念品分组

题目描述:

元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得 的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品, 并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。

你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。

输入格式

第 1 行包括一个整数 w,为每组纪念品价格之和的上限。

第 2 行为一个整数 n,表示购来的纪念品的总件数。

第 3∼n+2 行每行包含一个正整数 pi​(5≤pi​≤w) ,表示所对应纪念品的价格。


输出格式

包含一个整数,即最少的分组数目。


数据范围

50% 的数据满足:1≤n≤15。

100% 的数据满足:1≤n≤30000,80≤w≤200。

示例:

输入:
100
9
90
20
20
30
50
60
70
80
90

输出:
6

 

简单的排序+贪心。分组数最少,即满足情况最少数。由于每组数目最大不超过2个,则从两边分别遍历!

最小数加最大数若满足题意则继续,若不满足 则找第二大的数继续进行。

 

代码:

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

void answer(){
    int w, n, res = 0;
    cin >> w;
    cin >> n;
    vector<int> price(n);
    for(int i = 0; i < n; i++){
        cin >> price[i];
    }
    sort(price.begin(), price.end());
    int first = 0, second = n - 1;
    while(first <= second){
        if(price[first] + price[second] <= w && first != second){
            res++;
            first++;
            second--;
        }
        else{
            res++;
            second--;
        }
    }
    cout << res;
}

int main() {
    answer();
}

 

标签:map,杂集,纪念品,题目,int,Vjudge,花生,植株,message
来源: https://www.cnblogs.com/LWHCoding/p/15773082.html