区域覆盖问题经典题目

喷水装置(二)

时间限制:3000 ms  |  内存限制:65535 KB

难度:4

描述
有一块草坪,横向长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
 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <math.h>
 4 #include <algorithm>
 5 using namespace std;
 6
 7 const int maxn = 10000 + 5;
 8
 9 struct node{
10     double a, b;
11 }A[maxn];
12
13 int cmp(node A, node B){
14     return A.a < B.a;
15 }
16
17 int main(){
18     int T;
19     scanf("%d", &T);
20     while(T--){
21         int n, w, h, cnt = 0, x, r;
22         scanf("%d%d%d", &n, &w, &h);
23         double start = 0, h1 = h*h*1.0/4, l;
24         for(int i = 0; i < n; i++){
25             scanf("%d%d", &x, &r);
26             if(r*r < h1){
27                 i--; n--;
28                 continue;
29             }
30             l = sqrt(r*r - h1);
31             A[i].a = x-l > 0 ? x-l : 0;
32             A[i].b = x+l < w ? x+l : w;
33         }
34         sort(A, A+n, cmp);
35         int i, k = -1;
36         while(start < w && A[k+1].a <= start){
37             double max1 = -1;
38             for(i = k+1; A[i].a <= start && i < n; i++){
39                 if(max1 < A[i].b){
40                     max1 = A[i].b;
41                     k = i;
42                 }
43             }
44             start = max1;
45             cnt++;
46         }
47         printf("%d\n", start < w ? 0 : cnt);
48     }
49 }

时间: 2024-08-28 10:26:46

区域覆盖问题经典题目的相关文章

uva 10382 - Watering Grass(区域覆盖问题)

Sample Input 8 20 2 5 3 4 1 1 2 7 2 10 2 13 3 16 2 19 4 3 10 1 3 5 9 3 6 1 3 10 1 5 3 1 1 9 1 Sample Output 6 2 -1 题目大意: 有一块草坪,长为l,宽为w,在它的水平中心线上有n个位置可以安装喷水装置,各个位置上的喷水装置的覆盖范围为以它们自己的半径ri为圆.求出最少需要的喷水装置个数. 分析与总结: 这题的关键在于转化 根据这图可以看出,一个喷水装置的有效覆盖范围就是圆中间的那个矩

学习心得:《十个利用矩阵乘法解决的经典题目》from Matrix67

本文来自:http://www.matrix67.com/blog/archives/tag/poj大牛的博文学习学习 节选如下部分:矩阵乘法的两个重要性质:一,矩阵乘法不满足交换律:二,矩阵乘法满足结合律经典题目1 给定n个点,m个操作,构造O(m+n)的算法输出m个操作后各点的位置.操作有平移.缩放.翻转和旋转    这 里的操作是对所有点同时进行的.其中翻转是以坐标轴为对称轴进行翻转(两种情况),旋转则以原点为中心.如果对每个点分别进行模拟,那么m个操作总共耗时 O(mn).利用矩阵乘法可

[转]十个利用矩阵乘法解决的经典题目

好像目前还没有这方面题目的总结.这几天连续看到四个问这类题目的人,今天在这里简单写一下.这里我们不介绍其它有关矩阵的知识,只介绍矩阵乘法和相关性质.    不要以为数学中的矩阵也是黑色屏幕上不断变化的绿色字符.在数学中,一个矩阵说穿了就是一个二维数组.一个n行m列的矩阵可以乘以一个m行p列的矩阵,得到的结果是一个n行p列的矩阵,其中的第i行第j列位置上的数等于前一个矩阵第i行上的m个数与后一个矩阵第j列上的m个数对应相乘后所有m个乘积的和.比如,下面的算式表示一个2行2列的矩阵乘以2行3列的矩阵

矩阵经典题目七:Warcraft III 守望者的烦恼(矩阵加速递推)

https://www.vijos.org/p/1067 很容易推出递推式f[n] = f[n-1]+f[n-2]+......+f[n-k]. 构造矩阵的方法:构造一个k*k的矩阵,其中右上角的(k-1)*(k-1)的矩阵是单位矩阵,第k行的每个数分别对应f[n-1],f[n-2],,f[n-k]的系数.然后构造一个k*1的矩阵,它的第i行代表f[i],是经过直接递推得到的.设ans[][]是第一个矩阵的n-k次幂乘上第二个矩阵,f[n]就是ans[k][1]. 注意:用__int64 #in

十个利用矩阵乘法解决的经典题目

转载自    Matrix67: The Aha Moments 好像目前还没有这方面题目的总结.这几天连续看到四个问这类题目的人,今天在这里简单写一下.这里我们不介绍其它有关矩阵的知识,只介绍矩阵乘法和相关性质.    不要以为数学中的矩阵也是黑色屏幕上不断变化的绿色字符.在数学中,一个矩阵说穿了就是一个二维数组.一个n行m列的矩阵可以乘以一个m行p列的矩阵,得到的结果是一个n行p列的矩阵,其中的第i行第j列位置上的数等于前一个矩阵第i行上的m个数与后一个矩阵第j列上的m个数对应相乘后所有m个

[leetcode]53Maximum Subarray动态规划经典题目:最大子串问题

/** * Find the contiguous subarray within an array (containing at least one number) * which has the largest sum. For example, given the array [-2,1,-3,4,-1,2,1,-5,4], the contiguous subarray [4,-1,2,1] has the largest sum = 6. click to show more prac

矩阵乘法的经典题目_源自Matrix67_

嘛,都刷一遍好辣. 矩阵Am?n就是一个m行n列的数表. 考虑矩阵的乘法: C=A?B=∑aik?bkj 那么对于矩阵A的要求就是:A为m * n的矩阵 对于矩阵B的要求就是:B为n * p的矩阵 乘得的矩阵C的规模:m * p的矩阵 矩阵乘法是不满足交换律的.但它满足结合律和分配律. 经典题目1 给定n个点,m个操作,构造O(m+n)的算法输出m个操作后各点的位置.操作有平移.缩放.翻转和旋转 然后盗图 考虑实际上这个变换对应着一个类似于线性变换的东西,我们显然是可以用矩阵来搞的. 而对于翻转

矩阵经典题目八:hdu 2175 How many ways??

http://acm.hdu.edu.cn/showproblem.php?pid=2157 给定一个有向图,问从A点恰好走k步(允许重复经过边)到达B点的方案数mod p的值 把给定的图转为邻接矩阵,即A(i,j)=1当且仅当存在一条边i->j.令C=A*A,那么C(i,j)=ΣA(i,k)*A(k,j),实际上就等于从点i到点j恰好经过2条边的路径数(枚举k为中转点).类似地,C*A的第i行第j列就表示从i到j经过3条边的路径数.同理,如果要求经过k步的路径数,我们只需要二分求出A^k即可.

动态规划经典题目:最大连续子序列和

最大连续子序列和问题 给定k个整数的序列{N1,N2,...,Nk },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j <= k.最大连续子序列是所有连续子序中元素和最大的一个,例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{11,-4,13},最大连续子序列和即为20. 注:为方便起见,如果所有整数均为负数,则最大子序列和为0. 解决这样一个问题是一个很有趣的过程,我们可以尝试着从复杂度比较高的算法