HDU 1264(离散化线段树;hash暴力)

╰半橙微兮° 2022-09-20 12:42 289阅读 0赞

题意:每行给出4个数字,分别为两个坐标值,这两个坐标为一个矩形的对角坐标,也就是说,这4个数字代表两个坐标从而确定了一个矩形。。当4个数字都为-1时,表示一组数据结束;当4个数字都为-2时,表示程序结束。求的是一组数据的各个矩形并下来覆盖的面积。

这道题目我用hash暴力解决:

  1. #include <cstdio>
  2. #include <cstring>
  3. bool rectangle[109][109];
  4. int main()
  5. {
  6. int a, b, c, d, result = 0;
  7. while (scanf("%d%d%d%d", &a, &b, &c, &d), 1)
  8. {
  9. if (a < 0)
  10. {
  11. printf("%d\n", result);
  12. if (a == -2) break;
  13. result = 0;
  14. memset(rectangle, false, sizeof rectangle);
  15. }
  16. if (a > c) a^=c^=a^=c;
  17. if (b > d) b^=d^=b^=d;
  18. for (int i = a; i < c; ++i)
  19. for (int j = b; j < d; ++j)
  20. if (rectangle[i][j] == false) rectangle[i][j] = true, ++result;
  21. }
  22. return 0;
  23. }

当然也可以用线段树离散化来求解:

  1. /*
  2. 线段树求矩形面积的并(离散化下先)
  3. 把X坐标排序离散,枚举每一个区间,然后扫描线段树,求的覆盖的Y的长度
  4. 然后 (X[i+1]-X[i]) *L 即是所求面积
  5. */
  6. #include<stdio.h>
  7. #include<string.h>
  8. #include<stdlib.h>
  9. #define NN 300
  10. #define Swap(a,b) (a=a^b,b=b^a,a=a^b)
  11. struct node{
  12. int r,l,val;
  13. }seg_tree[NN];
  14. struct Link{
  15. int low_x,low_y,high_x,high_y;
  16. }link[NN];
  17. int X[NN];
  18. int len_l,len_seg,len_x,val,get_ans;
  19. int cmp(const void *a,const void *b){
  20. return *(int *)a - *(int *)b;
  21. }
  22. void Init(int root,int l,int r)
  23. {
  24. int mid = (l+r)>>1;
  25. seg_tree[root].l = l;
  26. seg_tree[root].r = r;
  27. seg_tree[root].val = 0;
  28. len_seg = len_seg < root ? root : len_seg;
  29. if(r-l == 1)return ;
  30. Init(root*2,l,mid);
  31. Init(root*2+1,mid,r);
  32. }
  33. void insert(int root ,int l,int r){
  34. int mid = (seg_tree[root].l+seg_tree[root].r)>>1;
  35. if(root > len_seg ) return ;
  36. if(l <= seg_tree[root].l && r >= seg_tree[root].r)
  37. seg_tree[root].val = val;
  38. else if(r<=mid)insert(root*2,l,r);
  39. else if(l>=mid)insert(root*2+1,l,r);
  40. else {
  41. insert(root*2,l,mid);
  42. insert(root*2+1,mid,r);
  43. }
  44. return ;
  45. }
  46. void get_seg(int root)
  47. {
  48. if(root > len_seg ) return ;
  49. if(seg_tree[root].val == val){ //用来区分不同区间的Y的长度
  50. get_ans+=(seg_tree[root].r-seg_tree[root].l);
  51. return ;
  52. }
  53. get_seg(root*2);
  54. get_seg(root*2+1);
  55. }
  56. int main()
  57. {
  58. int i,j,ans,x1,x2,y1,y2;
  59. Init(1,0,100);
  60. while(scanf("%d%d%d%d",&x1,&y1,&x2,&y2)){
  61. ans=len_l=len_x=0;
  62. if(x1>x2)Swap(x1,x2);
  63. if(y1>y2)Swap(y1,y2);
  64. X[len_x++] = x1;
  65. X[len_x++] = x2;
  66. link[len_l].low_x = x1;
  67. link[len_l].low_y = y1;
  68. link[len_l].high_x = x2;
  69. link[len_l++].high_y=y2;
  70. while(scanf("%d%d%d%d",&x1,&y1,&x2,&y2)){
  71. if(x1 == -1 || x1 == -2)break;
  72. if(x1>x2)Swap(x1,x2);
  73. if(y1>y2)Swap(y1,y2);
  74. X[len_x++] = x1;
  75. X[len_x++] = x2;
  76. link[len_l].low_x = x1;
  77. link[len_l].low_y = y1;
  78. link[len_l].high_x = x2;
  79. link[len_l++].high_y=y2;
  80. }
  81. qsort(X,len_x,sizeof(int),cmp);
  82. for(i=0;i<len_x-1;i++){
  83. if(X[i] == X[i+1])continue;
  84. val++;//保证了不同区间 线段树中val的值的不同,达到一次建树,多次使用的效果!
  85. for(j=0;j<len_l;j++){
  86. if(link[j].low_x <= X[i] && link[j].high_x >= X[i+1])
  87. insert(1,link[j].low_y,link[j].high_y);
  88. }
  89. get_ans=0;
  90. get_seg(1);
  91. ans += (X[i+1]-X[i])*get_ans;
  92. }
  93. printf("%d\n",ans);
  94. if(x1 == -2)break;
  95. }
  96. return 0;
  97. }

发表评论

表情:
评论列表 (有 0 条评论,289人围观)

还没有评论,来说两句吧...

相关阅读

    相关 POJ 2528 线段+离散

        [POJ 2528][]      关键在于插入数据的顺序------从上往下依次插入每张海报,这样后插入的海报不可能覆盖先插入的海报,因此插入一张海报时,如果发现海