pku3277 City Horizon.(离散化+二分查找)

还是用到了离散化和二分查找的一个题目,题目是求每段线段可以达到最大的矩形面积,再求总和。
  1. /*  Name: City Horizon 
  2.   Date: 31-07-08 17:06
  3.   Description: 离散化+二分查找 用了个链表
  4. */
  5. #include<stdio.h>
  6. #include<stdlib.h>
  7. #include<algorithm>
  8. #define pr printf
  9. __int64 x[100003];
  10. int b[100003];
  11. struct stt{
  12.     int s,e,h;
  13. }a[50003];
  14. int c[100003];
  15. int cmp(const void * a,const void * b){
  16.         return (int)(*(__int64 *)a-*(__int64 *)b);
  17.     }
  18. int cmp2(const void * b,const void *a){
  19.     return ((stt *)a)->h-((stt *)b)->h;
  20.     }
  21. //二分查找排序数组,返回匹配元素位置
  22. int search_bin(__int64 *t,__int64 k,int start,int end)
  23. {  // t为待查数组,k为匹配元素,start数组起始位置,end数组结束位置
  24.        int low=start,high=end-1,mid;
  25.        while (low<=high)
  26.            {
  27.              mid=(low+high)/2;
  28.              if (k==t[mid]) return mid;
  29.                  else if (k<t[mid]) high=mid-1;
  30.                 else low=mid+1;
  31.            }
  32.         return -1;
  33. }
  34. int main(){
  35.     int i,n,s,e,h,k;
  36.     scanf("%d",&n);
  37.     FILE *pp=fopen("temp.txt","w");
  38.     for(i=0,k=0;i<n;i++,k++)
  39.     {
  40.         scanf("%d%d%d",&a[i].s,&a[i].e,&a[i].h);
  41.         x[k]=a[i].s,x[++k]=a[i].e;
  42.     }
  43.     for(i=0;i<2*n;i++)c[i]=0;
  44.     qsort(x,2*n,sizeof(__int64),cmp);//将x坐标离散
  45.     qsort(a,n,sizeof(a[1]),cmp2);//按高度排序
  46.     __int64 sum=0,len; 
  47.     int x1,j,x2,next;
  48.     for(i=0;i<2*n-1;i++)
  49.     {
  50.         b[i]=i+1;//初始化链表
  51.     }
  52.     for(i=0;i<n;i++)
  53.     {
  54.         s=a[i].s,e=a[i].e,h=a[i].h;
  55.         x1=search_bin(x,s,0,2*n);
  56.         x2=search_bin(x,e,0,2*n);
  57.         len=0;
  58.         for(j=x1;j<x2 && j<2*n;j=next)//链表是关键,保证了每个点只会便利一次
  59.             {
  60.                 if(c[j]==0)//没有访问过的点
  61.                {
  62.                     c[j]=1;
  63.                     len+=(x[j+1]-x[j]);
  64.                     next=b[j];
  65.                     b[j]=x2;
  66.                }else next=b[j];//被覆盖的点根据链表找到下一点索引
  67.             }    
  68.             sum+=len*h;
  69.     }   
  70.        pr("%I64d/n",sum);
  71.        scanf("%d",&i);
  72. }
  73. /*
  74. 4
  75. 1 15 1
  76. 3 7 4
  77. 3 12 5
  78. 5 8 3
  79. */
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值