?? 房子投影 堆.txt
字號:
#include <stdio.h>
#include <iostream>
#include <math.h>
#include <algorithm>
using namespace std;
//NOJ 房子投影 堆結構
/*
4
1 4 3
2 7 2
6 9 4
9 10 3
6
1 5 10
3 8 8
4 7 20
8 9 40
10 14 30
12 13 15
輸出
28
258
*/
typedef struct xhigh
{
__int64 x;//高度的橫坐標
__int64 y;//高度的縱坐標
bool add;//是房子的左豎線還是右豎線
__int64 hhouse;//對應哪一個房子
}xhigh;
#define NMAX 85000
__int64 house[NMAX];//house[i],i房子的左豎線在heap中的下標
__int64 heap[NMAX];//高度優先堆
__int64 heaphou[NMAX];//heaphou[i],堆[i]的豎線對應哪個房子
xhigh shuru[NMAX*2];
xhigh chuli[NMAX*2];
void insert_heap(__int64 high,__int64 num,__int64 newhou)
{//把高度high插入到heap[1..num-1]中,高度high對應編號為newhou的房子
__int64 rc,j;
heap[num]=rc=high;
for(j=num/2;j>=1;j/=2)
{
if(heap[j]<rc)
{
heap[num]=heap[j];
heaphou[num]=heaphou[j];
house[heaphou[num]]=num;
}
else break;
num=j;
}
heap[num]=rc;
heaphou[num]=newhou;
house[heaphou[num]]=num;
}
void delete_heap(__int64 delenum,__int64 num)
{//將heap[1..num]中編號為delenum的元素刪除
__int64 temp,j,temphou,rc,start;
//先將要刪除的元素和堆尾元素調換位置,然后刪除堆尾元素
//注意heaphou[],和house也要修改
temp=heap[num];heap[num]=heap[delenum];heap[delenum]=temp;
temphou=heaphou[num];
heaphou[num]=heaphou[delenum];
heaphou[delenum]=temphou;
house[heaphou[delenum]]=delenum;
house[heaphou[num]]=num;
heap[num]=0;//把堆尾元素給sm掉了
rc=heap[delenum];
start=delenum;
if((delenum*2<num&&heap[delenum]<heap[delenum*2])||(
delenum*2+1<num&&heap[delenum]<heap[delenum*2+1]))
{//向下調整
for(j=delenum*2;j<num;j*=2)
{
if(j<num-1&&heap[j]<heap[j+1]) j++;
if(rc>heap[j]) break;
heap[delenum]=heap[j];heaphou[delenum]=heaphou[j];
house[heaphou[delenum]]=delenum;
delenum=j;
}
heap[delenum]=rc;
heaphou[delenum]=temphou;
house[heaphou[delenum]]=delenum;
}
delenum=start;
rc=heap[delenum];
if(delenum/2>=1&&heap[delenum/2]<heap[delenum])
{//向上調整
for(j=delenum/2;j>=1;j/=2)
{
if(rc<heap[j]) break;
heap[delenum]=heap[j];
heaphou[delenum]=heaphou[j];
house[heaphou[delenum]]=delenum;
delenum=j;
}
heap[delenum]=rc;
heaphou[delenum]=temphou;
house[heaphou[delenum]]=delenum;
}
}
bool cmpx(struct xhigh a,struct xhigh b)
{
//注意排序的原則:
//橫坐標小的在前,橫坐標一樣的,左豎線在前(靠,不然會刪除未出現的豎線)
return a.x<b.x||(a.x==b.x&&a.add==true&&b.add==false);
}
__int64 solve(int num)
{
__int64 i,lastx,sql=0,heapnum,ss;
for(i=1;i<=2*num;i++)
chuli[i]=shuru[i];
sort(chuli+1,chuli+1+num*2,cmpx);
lastx=chuli[1].x;
heapnum=0;
for(i=1;i<=2*num;i++)
{
ss=(chuli[i].x-lastx)*heap[1];
sql+=ss;
if(chuli[i].add==true)
{ //左豎線
heapnum++;
insert_heap(chuli[i].y ,heapnum,chuli[i].hhouse);
}
else
{ //右豎線
delete_heap(house[chuli[i].hhouse],heapnum);
heapnum--;
}
lastx=chuli[i].x;//不解釋。。。
}
return sql;
}
int main()
{
__int64 num,i,ta,tb,th,j;
while(scanf("%I64d",&num)!=EOF)
{
for(i=1,j=1;i<=num;i++)
{
scanf("%I64d%I64d%I64d",&ta,&tb,&th);
shuru[j].x=ta;
shuru[j].y=th;
shuru[j].add=true;
shuru[j].hhouse=i;
j++;
shuru[j].x=tb;
shuru[j].y=th;
shuru[j].add=false;
shuru[j].hhouse=i;
j++;
}
printf("%I64d\n",solve(num));
}
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -