D4——贪心练习

习题课,无知识点

数列极差问题

题目描述

在黑板上写了N个正整数组成的一个数列,进行如下操作: 每次擦去其中的两个数a和b,然后在数列中加入一个数a×b+1,如此下去直至黑板上 剩下一个数,在所有按这种操作方式最后得到的数中,最大的为max,最小的为min, 则该数列的极差定义为M=max-min。

请你编程,对于给定的数列,计算极差。

输入描述

输入包含多个测试集。每个测试集的第一个数N表示 正整数序列长度(0<=N<=50000),随后是N个正整数。N为0表示输入结束

输出描述

每个结果一行

样例

输入

复制代码
3
1
2
3
0

输出

复制代码
2

代码

cpp 复制代码
#include<iostream>
#include<queue>
using namespace std;
int n,a[50005];
long long c,j;
int main(){
	while(cin>>n&&n!=0){
		priority_queue<int>q;
		priority_queue<int,vector<int>,greater<int> >b;
		for(int i=1;i<=n;i++){
			cin>>a[i];
			q.push(a[i]);
			b.push(a[i]);
		}
		while(q.size()>1){
			int x=q.top();
			q.pop();
			int y=q.top();
			q.pop();
			q.push(x*y+1);
		}
		while(b.size()>1){
			int x=b.top();
			b.pop();
			int y=b.top();
			b.pop();
			b.push(x*y+1);
		}
		cout<<b.top()-q.top()<<"\n";
	}
	return 0;
}

喷水装置(二)

题目描述

有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=100000)个点状的喷水装置,每个喷水装置i喷水的效果是让以它为中心半径为Ri的圆都被润湿。请在给出的喷水装置中选择尽量少的喷水装置,把整个草坪全部润湿。

输入描述

第一行输入一个正整数N表示共有n次测试数据。每一组测试数据的第一行有三个整数n,w,h,n表示共有n个喷水装置,w表示草坪的横向长度,h表示草坪的纵向长度。随后的n行,都有两个整数xi和ri,xi表示第i个喷水装置的的横坐标(最左边为0),ri表示该喷水装置能覆盖的圆的半径。

输出描述

每组测试数据输出一个正整数,表示共需要多少个喷水装置,每个输出单独占一行。如果不存在一种能够把整个草坪湿润的方案,请输出0。

样例

输入

复制代码
2
2 8 6
1 1
4 5
2 10 6
4 5
6 5

输出

复制代码
1
2
cpp 复制代码
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
using namespace std;
struct qj {
	double a,b;
} q[10005];
bool cmp(qj n,qj m) {
	return n.a<m.a;
}
int n,t,w,h,r,x,num;
int main() {
	cin>>t;
	while(t--) {
		num=0;
		cin>>n>>w>>h;
		double H=h/2.0;
		for(int i=1; i<=n; i++) {
			cin>>x>>r;
			if(r>H) {
				double t=sqrt(r*r-H*H);
				q[++num].a=x-t;
				q[num].b=x+t;
			}
		}
		if(num==0) {
			cout<<0<<"\n";
			continue;
		}
		sort(q+1,q+num+1,cmp);
		int cnt=0,k=0,f=0;
		double pr=0;
		for(int i=1; i<=num; i++) {
			if(pr>=w) {
				break;
			}
			int t=i,ma=q[i].b,ans=i;
			while(q[t].a<=pr&&t<=num) {
				if(ma<q[t].b) {
					ma=q[t].b;
					ans=t;
				}
				t++;
			}
			if(q[ans].a<=pr) {
				cnt++;
				i=ans;
				pr=q[i].b;
			} else {
				cout<<0<<"\n";
				f=1;
				break;
			}
		}
		if(!f) {
			cout<<cnt<<"\n";
		}
	}
	return 0;
}

愤怒的家雀子

题目描述

在森林里有一排树。第i棵树的高度是Di。有一只家雀儿,它在第一棵树上,它只有到最后一棵树的顶端才能找到食物

然而,这只鸟力气比较小,无法直接飞到那里。小鸟如果在第i棵树,那么他可以跳到第i+1,i+2,...,i+k棵树,然后必须休息。而且,向上飞要比向下飞难得多。 如果雏鸟跳到一棵不矮于当前树的树,那么他的劳累值会+1,否则不会累积疲劳值(可以滑翔)。 我们如果在飞翔的过程中有目的地选择小鸟降落的树,这样整个飞行过程就不会那么累。

输入描述

第一行1个整数N表示树的个数(2 <= N <= 10^6);

第二行N个整数分别表示第i棵树的高度D[i];

第三行1个整数Q(1 <= Q <= 25)表示K的个数;

接下来Q行,每行1个整数表示K。

输出描述

输出Q行,每行1个整数表示家雀儿在此K情况下最小化的劳累值。

样例

输入

复制代码
9
4 6 3 6 3 7 2 6 5
2
2
5

输出

复制代码
2
1

提示

K=2时

家雀儿可以从第一棵树向右飞停在第三、五、七、八、九号树上,它的疲劳值是从第三棵树到第五棵树,从第七树到第八树的飞行过程中积累的,也可以停在第三、五、七、九号树上。

代码

cpp 复制代码
#include<iostream>
using namespace std;
int n,d[10000005],q,k;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>d[i];
	} 
	cin>>q;
	while(q--){
		cin>>k;
		int pr=1,sum=0;
		while(pr+k<n){
			int hm=-1,t=pr,ma=-1,t1=pr;
			for(int i=pr+1;i<=pr+k;i++){
				if(d[i]<d[pr]){
					if(hm<d[i]){
						hm=d[i];
						t=i;
					}
				}
				if(d[i]>=ma){
					ma=d[i];
					t1=i;
				}
			}
			if(hm==-1){
				sum++;
				pr=t1;
			}
			else{
				pr=t;
			}
		}
		if(d[pr]<=d[n]){
		    sum++;
		}
		cout<<sum<<"\n";
	}
	return 0;
}
相关推荐
安大小万6 分钟前
C++ 学习:深入理解 Linux 系统中的冯诺依曼架构
linux·开发语言·c++
田梓燊20 分钟前
图论 八字码
c++·算法·图论
Tanecious.1 小时前
C语言--数据在内存中的存储
c语言·开发语言·算法
去往火星1 小时前
opencv在图片上添加中文汉字(c++以及python)
开发语言·c++·python
Bran_Liu1 小时前
【LeetCode 刷题】栈与队列-队列的应用
数据结构·python·算法·leetcode
kcarly2 小时前
知识图谱都有哪些常见算法
人工智能·算法·知识图谱
CM莫问2 小时前
<论文>用于大语言模型去偏的因果奖励机制
人工智能·深度学习·算法·语言模型·自然语言处理
程序猿零零漆2 小时前
《从入门到精通:蓝桥杯编程大赛知识点全攻略》(五)-数的三次方根、机器人跳跃问题、四平方和
java·算法·蓝桥杯
Zfox_3 小时前
【Linux】进程间关系与守护进程
linux·运维·服务器·c++
无限码力3 小时前
路灯照明问题
数据结构·算法·华为od·职场和发展·华为ode卷