題目鏈接:
題目大意:
數據範圍:
解題思路:
外話:
詳見代碼:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
using namespace std;
typedef long long LL;
const int inf = 1 << 30;
const LL INF = 1LL << 60;
const int MaxN = 2e5;
//const double PI = 3.1415926535897932384626;
const double PI = acos(-1);
LL sx, sy, tx, ty;
int n, tot;
double res;
struct point
{
LL x, y;
}tmp[MaxN + 5];
bool cmpx(point a, point b) {
if(a.x == b.x) return a.y < b.y;
else return a.x < b.x;
}
//----------------LIS---------------------
int len;
LL a[MaxN + 5], d[MaxN + 5];
int bin_search(LL x) {
int l = 0, r = len;
int mid = 0, ans = 0;
while(l <= r) {
mid = (l + r) >> 1;
if(d[mid] >= x) ans = mid, r = mid - 1;
else l = mid + 1;
}
return ans;
}
void get_LIS(bool c)
{
len = 0;
d[len] = -INF;
//初始d[0] == 0的,如果LIS中有0,就會少算一個
if(c == 1) {
for(int i = 1; i <= tot; i++)
a[i] = tmp[i].y;
}
else {
//求下降時將數組倒過來求最長
for(int i = 1; i <= tot; i++)
a[i] = tmp[tot - i + 1].y;
}
for(int i = 1; i <= tot; i++) {
if(a[i] > d[len]) d[++len] = a[i];
else {
int pos = bin_search(a[i]);
d[pos] = a[i];
}
}
}
//----------------------------------------
int main()
{
tot = 0;
res = 0.0;
scanf("%lld %lld %lld %lld", &sx, &sy, &tx, &ty);
if(sx > tx) {
//讓起點在左邊
swap(sx, tx); swap(sy, ty);
}
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
LL x, y;
scanf("%lld %lld", &x, &y);
//將在 起點和終點所形成的矩形 中的點給摳出來
if((min(sx, tx) <= x && x <= max(sx, tx)) && (min(sy, ty) <= y && y <= max(sy, ty)))
tmp[++tot].x = x, tmp[tot].y = y;
}
sort(tmp + 1, tmp + tot + 1, cmpx);
if(sy > ty) {
//取最長下降子序列
get_LIS(0);
}
else if(sy <= ty) {
//取最長上升子序列
get_LIS(1);
}
int num = min(abs(tx - sx), abs(ty - sy)) + 1;
if(len == num) {
//肯定會直線經過一個噴泉,其他都是拐角
res = (100.0 * (abs(tx - sx) + abs(ty - sy)) - 20.0 * (LL)len) + (LL)(len - 1) * 5 * PI + 10 * PI;
}
else {
//全是拐角經過
res = (100.0 * (abs(tx - sx) + abs(ty - sy)) - 20.0 * (LL)len) + (LL)len * 5 * PI;
}
printf("%.15lf\n", res);
return 0;
}