ACM-ICPC 2018 徐州赛区网络预赛 G. Trace
题意
后浪推前浪,每个浪是一个矩形,由两条边组成,后形成的浪会把之前浪的边吞掉,问最后剩下的边的总长度。
思路
越后生成的浪保留的边越多,所以我们反过来放就保证我们先放的不会被吞,采用集合存放点,每次放新的点的时候查找到他正左端的点和正右端的点,在ans上加上横纵坐标之差就完成了。
题目保证没有任两个浪相互包含,这使得我们这样的算法总是合理的。
代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef pair<int,int> PII; 4 const int N=5e4+7; 5 PII point[N]; 6 int main() 7 { 8 set<PII> se; 9 int n; 10 scanf("%d",&n); 11 for(int i=0,a,b;i<n;i++) 12 { 13 scanf("%d%d",&a,&b); 14 point[i] = make_pair(a,b); 15 } 16 long long ans=point[n-1].first+point[n-1].second; 17 se.insert(make_pair(0,1e7+5)); 18 se.insert(make_pair(1e7+5,0)); 19 se.insert(point[n-1]); 20 for(int i=n-2;i>=0;i--) 21 { 22 auto it=se.lower_bound(point[i]); 23 ans+=point[i].second-it->second; 24 it--; 25 ans+=point[i].first-it->first; 26 se.insert(point[i]); 27 } 28 printf("%lld\n",ans); 29 }