2 solutions
-
1
这道题跟活动安排那道题是一模一样的原理,在活动安排那道题中,要保证活动之间时间不冲突,能举办的活动的最大个数,而此题要求的是线段之间互不重复的个数的最大值,时间是线性的,线段也是线性的,因此此题完全可以按照线段的截止长度从小到大进行排序,如果这样可以尽量保证上一个线段结束后后一个线段马上开始,类似活动安排,上一个活动结束后,后一个活动马上进行,如果上一个活动结束后,那么就舍弃掉后一个活动,让上一个活动继续与后面进行对比
#include<stdio.h> #include<stdlib.h> /*要判断线段之间两两没有重复的部分,这让我想起了活动安排的例题 ,选出互相兼容的活动的最大个数,按线段结尾的数从小到大的顺序进行排列,如果b<=a则没有重叠的部分 */ typedef struct line{ int a; int b; }Lin; Lin array[1000001]; int comp(const void *a,const void *b){ //将void *强制转化为结构体指针类型 Lin *c = (Lin *)a; Lin *d = (Lin *)b; return c->b-d->b; } int main(){ int n; int number = 1; scanf("%d",&n);//输入n表示行数 for(int i=0; i<n; i++){ scanf("%d %d",&array[i].a,&array[i].b);//输入a和b描述线段 } qsort(array,n,sizeof(array[0]),comp); for(int i=0; i<n-1; i++){ if(array[i].b <= array[i+1].a){ number++; } else{ array[i+1] = array[i]; } } printf("%d",number); }
-
0
贪心题
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #include<vector> #include<string> using namespace std; const int N = 1e6 + 5; struct line //存放每个线段的左右端 { int l; int r; } lin[N]; int cmp(line x, line y) //自定义下面排序结构体的顺序, //让线段右边大的放后面,同时保证当线段右边一样大的时候左边大的放后面, //便于最后的比较 //这里可以自己把代码抄来运行一下看运行结果理解理解 { if (x.r != y.r) return x.r < y.r; else return x.l < y.l; } int main() { int n, ans = 0; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d%d", &lin[i].l, &lin[i].r);; sort(lin, lin + n, cmp); int begin = 0; for (int i = 0; i < n; i++) { if (lin[i].l >= begin) //最左边的比上一个最右边的还要大,那么一定没有香蕉处 { begin = lin[i].r; ans++; } } printf("%d\n", ans); return 0; }
结束撒花
- 1
Information
- ID
- 96
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 6
- Tags
- # Submissions
- 142
- Accepted
- 44
- Uploaded By