样例输入
3
1 4
4 1
3 3
样例输出
10
解题思路
It’s guaranteed that a wave will not cover the other completely.
题目保证了不完全覆盖,并且保证x1<=x2与y1<=y2不同时成立,所以大大简化难度。
首先考虑n==2的情况,假设第二个点(x2,y2)已经画在坐标上了,然后第一个点(x1,y1)两种情况
1.如果x1 < x2,那么y1 > y2,那么ans += x1+y1-y2;
2.如果x1 > x2,那么y1 < y2,那么ans += y1+x1-x2;
将x y分开看可以发现如果x是当前出现过的最小值,ans直接加上x,反之,ans加上x后再减去比x小的值,y同理。
推广到n>2的话,从后往前遍历,如果x是当前出现过的最小值,ans直接加上x,反之,ans加上x后再减去比x小的最大值,y同理。
注意一个小细节
代码22行与29行,需要vx.lower_bound(),不能用lower_bound(vx.begin(),vy.begin,),实测第二个会超时,可能是因为内部实现不同吧。。。
AC代码
#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
struct node
{
int a;
int b;
}que[100005];
int main()
{
set<int>vx, vy;
int n;
long long ans = 0;
int maxx = 0;
int maxy = 0;
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d%d", &que[i].a, &que[i].b);
for (int i = n - 1; i >= 0; i--)
{
set<int>::iterator it = vx.lower_bound(que[i].a);
if (it != vx.begin())
ans += que[i].a - *(--it);
else
ans += que[i].a;
vx.insert(que[i].a);
set<int>::iterator itit = vy.lower_bound(que[i].b);
if (itit != vy.begin())
ans += que[i].b - *(--itit);
else
ans += que[i].b;
vy.insert(que[i].b);
}
printf("%lld\n", ans);
}