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