[贪心练习]一补题报告

                                           喷水装置(二)

时间限制:1秒        内存限制:128M

题目描述

  有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=10000)个点状的喷水装置,每个喷水装置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
#include<iostream>
#include<algorithm>
using namespace std;
int w,n,h,x,r,t;
struct node{
    double l,r;
}a[10005];
int cnt=0;
bool cmp(node x,node y){
    return x.l<y.l;
}
int main(){
    scanf("%d",&t);
    while(t--){
    	cnt=0;
        scanf("%d%d%d",&n,&w,&h);
        double H=0.5*h;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&x,&r);  
            if(r>H){
                double d=sqrt(r*r-H*H);
                a[cnt].l=x-d;
                a[cnt++].r=x+d;
            }
        }
        double sum=0,length;
        int ans=0,F,i=0;
        sort(a,a+cnt,cmp);
        while(sum<w){
        	F=0,length=0;
            for(;i<n&&a[i].l<=sum;i++){
               if(length<a[i].r-sum){
               	F=1,length=a[i].r-sum;
			   }
            }
            if(F){
                ans++;
                sum+=length;
            }
            else{
            	printf("0\n");
            	break;
			}
        }
        if(F){
            printf("%d\n",ans);
        }
    }
    return 0;
}

这题首先是要把它的面积求出来,用面积覆盖来去解决

一开始做题的时候没有想到他需要用勾股定理来解,就是很普通的,把它们的直径求出来之后,做错了

总的来说,这道题就是要把它从前到后遍历,选择最长区间,以这个区间的右端点为新的起点,继续选择,找不到输出0

                                         数列极差问题

时间限制:1秒        内存限制:128M

题目描述

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

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

输入描述

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

输出描述

每个结果一行

样例

输入

3
1
2
3
0

输出

2

#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
int n,m,w,h,N,maxx=-1e9,minn=1e9,a[10086];
int main(){
	while(cin>>n&&n){
		priority_queue<int>q1,q2;
		for(int i=1;i<=n;i++){
			cin>>a[i];
		}
		for(int i=1;i<=n;i++){
			q1.push(a[i]);
			q2.push(-a[i]);
			
		}
		for(int i=1;i<=n-1;i++){
			int x=q1.top();
			q1.pop();
			int y=q1.top();
			q1.pop();
			int xx=-q2.top();
			q2.pop();
			int yy=-q2.top();
			q2.pop();
			q1.push(x*y+1);
			q2.push(-(xx*yy+1));
		}
		int minn=q1.top();
		int maxx=-q2.top();
		cout<<maxx-minn<<endl;
	}
    return 0;
}

这一题是三题之中最简单的一个

思路很好想,就是把它从小到大遍历之后从大到小,和,从小到大把它累乘后加一存到一个变量里面再用大的变量减小的变量,最后输出

当然,这只能得20分

正解就是把它存到一个队里面,然后循环定义变量取队头输出,然后再定义变量,再取队头再输出,然后用它乘后加一以此往复,最后maxx-minn就好了

                                                油问题

时间限制:1秒        内存限制:128M

题目描述

你需要驾驶一辆卡车行驶L单位的距离。最开始时,卡车上有P单位的汽油。卡车每开1单位距离需要消耗1单位的汽油。
如果在途中车上的汽油耗尽,卡车就无法继续前进,因而无法到达终点。在途中一共有N个加油站。第i个加油站在距离起点Ai单位距离的地方,最多可以给卡车加Bi单位的汽油。假设卡车的燃料箱的容量是无限大的,无论加多少油都没有问题,那么请问卡车是否能到达终点、。如果可以,最少需要加多少次油?如果可以到达终点,输出最少的加油次数,否则输出-1。
限制条件:
1≤N≤10000
1≤L≤1000000,1≤P≤1000000
1≤Ai<L,1≤Bi≤100

输入描述

第一行用三个正整数描述,第一个正整数表示加油站个数,第二个正整数表示行驶距离,第三个正整数表示卡车原有多少汽油。
第二行输入每个加油站距离起点的距离。
第三行输入每个加油站可以给卡车加多少油。

输出描述

输出一行一个整数,表示最少需要加多少次油。

样例

输入

4 25 10
10 14 20 21
10 5 2 4

输出

2

提示

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
struct node {
    int a; 
    int b;
};
bool cmp(node x,node y) {
    return x.a < y.a; 
}
int main() {
    int n, L, P;
    cin >> n >> L >> P;

    vector<node> station(n);
    
    for (int i = 0; i < n; i++) {
        cin >> station[i].a;
    }
    
    for (int i = 0; i < n; i++) {
        cin >> station[i].b;
    }
    station.push_back({L, 0}); 
    n++;
    sort(station.begin(), station.end(), cmp);

    priority_queue<int> heap; 
    int ans = 0;
    int pos = 0; 
    int tank = P;

    for (int i = 0; i < n; i++) {
        int dist = station[i].a - pos;
        while (tank < dist) {
            if (heap.empty()) {
                cout << "-1" << endl;
                return 0;
            }
            tank += heap.top(); 
            heap.pop();
            ans++; 
        }

        tank -= dist; 
        pos = station[i].a; 
        heap.push(station[i].b);
    }

    cout << ans << endl;
    return 0;
}

【题目分析】
1.设置一个最大堆,用来存储经过加油站的汽油量
2.按照从起点至终点的方向,遍历各个加油站之间的距离
3.每次需要走两个加油站之间的距离d,如果发现汽油不够走距离个汽油量添加,直到可以足够走距离d
4.如果把最大堆的汽油都添加仍让不够行进距离d,则无法达到重点当前油量p减少d
5.将当前加油站油量添加至最大堆

  • 17
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值