- 区域的包容最大数
主要是排列,先按照一种变量排再按照其余的排。这个方法比较的方便也很巧妙,可以记住
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
const int MAXN = 5e3+10;
struct node{
int l,w,vis;
}G[MAXN];
bool cmp(node a,node b){
if(a.w>b.w)
return 0;
else if(a.w==b.w&&a.l>b.l)
return 0;
return 1;
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
memset(G,0,sizeof(G));
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d%d",&G[i].l,&G[i].w);
}
sort(G,G+n,cmp);
int cnt=0;
for(int i=0;i<n;i++){
if(!G[i].vis){
cnt++;
int flag=G[i].l;
for(int j=i+1;j<n;j++){
if(!G[j].vis&&G[j].l>=flag){
G[j].vis=1;
flag=G[j].l;
}
}
}
}
printf("%d\n",cnt);
}
return 0;
}
- 区间的区域覆盖
区间的区域覆盖问题:总体思想就是贪心算法
给定一个区间和几条线段的起点终点,求最少多少条线段就可以覆盖住
1.将每一个线段按照左端点递增顺序排列
2.设置变量表示已经覆盖的区域,再在剩下的线段中找出左端点小于等于
已覆盖区域的右端点,右端点最远的加入,直到覆盖住全部区域
需要最少的线段进行覆盖,那么选取的线段尽量长。
flag可以理解为总区间的左端点,同时也是小区间的右端点,arr[i].left>flag在最初的阶段是非常必要的,后来的过程也就延续下来。
flag2表示的是真正意义上的右端点。
另外要说的是在每一次的最右端点的切换中都会重新回归到最初,也就是说将前边已经取到的部分无视,重新进行操作
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;;
#define maxn 10010
struct Node {
double left, right;
} arr[maxn];
bool cmp(Node a, Node b) {
return a.left < b.left;
}
int main()
{
int ncase, id, result;
int n, w, h, x, r;
scanf("%d", &ncase);
while (ncase--)
{
scanf("%d%d%d", &n, &w, &h);
result = id = 0;
while (n--)
{
scanf("%d%d", &x, &r);
if (r * 2 <= h)
continue;
double len = sqrt(r*r - (h/2.0)*(h/2.0));
arr[id].left = x - len;
arr[id++].right = x + len;
}
sort(arr, arr + id, cmp);
double flag = 0.0, flag2 = 0.0;
for (int i = 0; i != id; ++i)
{
if (arr[i].left <= flag + 1e-7)
{
if (arr[i].right > flag2)
flag2 = arr[i].right;
}
else
{
flag = flag2;
++result;
if (flag + 1e-7 >= w)
break;
if (arr[i].left > flag + 1e-7)
break;
--i;
}
}
if (flag2 + 1e-7 < w)
result = 0;
else if (flag + 1e-7 < flag2)
++result;
printf("%d\n", result);
}
return 0;
}
3.区间的最大无覆盖线段数
学校的小礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办。小刘的工作就是安排学校小礼堂的活动,每个时间最多安排一个活动。现在小刘有一些活动计划的时间表,他想尽可能的安排更多的活动,请问他该如何安排。
#include <iostream>
#include <algorithm>
#include <stdio.h>
using namespace std;
const int MAXN = 1e4+10;
struct node{
int left,right;
}G[MAXN];
bool cmp(node a,node b){
return a.right<b.right;
}
int main()
{
int T;
cin >>T;
while(T--){
int n;
cin >>n;
for(int i=0;i<n;i++){
cin >>G[i].left>>G[i].right;
}
sort(G,G+n,cmp);
int flag=0,cnt=0;
for(int i=0;i<n;i++){
if(G[i].left>flag){
flag=G[i].right;
cnt++;
}
}
cout <<cnt<<endl;
}
return 0;
}