2 solutions

  • 1
    @ 2022-2-17 16:21:59

    这道题跟活动安排那道题是一模一样的原理,在活动安排那道题中,要保证活动之间时间不冲突,能举办的活动的最大个数,而此题要求的是线段之间互不重复的个数的最大值,时间是线性的,线段也是线性的,因此此题完全可以按照线段的截止长度从小到大进行排序,如果这样可以尽量保证上一个线段结束后后一个线段马上开始,类似活动安排,上一个活动结束后,后一个活动马上进行,如果上一个活动结束后,那么就舍弃掉后一个活动,让上一个活动继续与后面进行对比

    #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
      @ 2022-2-18 17:50:32

      贪心题

      #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