2.3 校门外的树
解决这道题的关键是如何把多个有重叠的区域整理成互不重叠的若干个区域。我的解决方法的关键是把输入的各个区域按起始位置排序,然后再通过简单的数值比较和更新,就可以得到最后互补重叠的若干个区域。下面代码已经AC。
1 #include<stdio.h> 2 #include<stdlib.h> 3 int comp(const void *a,const void *b) 4 { 5 return ((int *)a)[0]-((int *)b)[0]; 6 } 7 8 int main(void) 9 { 10 int L,M,i=0,j=0; 11 int data[100][2]; 12 int result[100][2];//用于存储没有交集的区域 13 int sum = 0; 14 scanf("%d %d",&L,&M); 15 while(i<M) 16 { 17 scanf("%d %d",&data[i][0],&data[i][1]); 18 i++; 19 } 20 qsort(data,M,sizeof(int)*2,comp);//采用lib库中的快排 21 22 result[0][0] = data[0][0]; 23 result[0][1] = data[0][1]; 24 j=0; 25 //把有交集的区域合并 26 for(i=1;i<M;i++) 27 { 28 if(data[i][0]>result[j][1]) 29 { 30 result[++j][0] = data[i][0]; 31 result[j][1] = data[i][1]; 32 }else{ 33 if(data[i][1]>result[j][1]) 34 result[j][1] = data[i][1]; 35 } 36 } 37 38 for(i=0;i<=j;i++) 39 { 40 sum += (result[i][1]-result[i][0]+1); 41 } 42 printf("%d ",L+1-sum); 43 return 0; 44 }
思路二:《程序设计导引及在线实践》上提供了另一种思路,因为题中给的L和M的大小都不是很大,所以采用空间换时间的办法。定义一个总长为L的上线也就是10001的布尔数组,初始都是true,当一个区域被读进来时,就把这个区域的置为false,最后这个布尔数组中为true的个数就是剩下的树的数目。