小人从上往下掉的时候,比如区间[-50, 100], [0, 100]它可以从上一个100跳到下一个100.。。。。无语的神逻辑。。。从早晨wa到现在。T_T
按高度从大到小排序
f[i][0]表示到i层左端点的最小路径,f[i][1]表示到i层右端点的最小路径。
落下时判断第j层到第i层有没有其他的层。。。这个写了一个暴力,居然没有TLE。。。看来题目数据真的不怎么强。
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <ctime> #include <queue> #include <map> #include <sstream> #define CL(arr, val) memset(arr, (val), sizeof(arr)) #define REP(i, n) for((i) = 0; (i) < (n); ++(i)) #define FOR(i, l, h) for((i) = (l); (i) <= (h); ++(i)) #define FORD(i, h, l) for((i) = (h); (i) >= (l); --(i)) #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) ((l) + (r)) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) ((x) > 0 ? (x) : -(x)) typedef long long LL; const double eps = 1e-8; const int inf = ~0u>>2; using namespace std; const int N = 1024; struct node { int x1, x2, h; bool operator < (const node tmp) const { return h > tmp.h; } } l[N]; int f[N][2]; int main() { //freopen("data.in", "r", stdin); int t, n, x, y, mx; int i, j, k, tmp; bool flag; scanf("%d", &t); while(t--) { scanf("%d%d%d%d", &n, &x, &y, &mx); l[0].x1 = x; l[0].x2 = x; l[0].h = y; for(i = 1; i <= n; ++i) { scanf("%d%d%d", &l[i].x1, &l[i].x2, &l[i].h); f[i][1] = f[i][0] = inf; } sort(l, l + n + 1); f[0][0] = f[0][1] = 0; /*for(i = 0; i <= n; ++i) { printf("%d %d %d\n", l[i].x1, l[i].x2, l[i].h); }*/ for(i = 1; i <= n; ++i) { for(j = 0; j < i; ++j) { if(l[i].x1 <= l[j].x1 && l[i].x2 >= l[j].x1 && l[j].h - l[i].h <= mx) { //left flag = true; for(k = j + 1; k < i && flag; ++k) { if(l[k].x1 <= l[j].x1 && l[k].x2 >= l[j].x1) {flag = false; break;} } if(flag && f[j][0] != inf) { tmp = f[j][0] + l[j].h - l[i].h + iabs(l[j].x1 - l[i].x1); f[i][0] = min(f[i][0], tmp); tmp = f[j][0] + l[j].h - l[i].h + iabs(l[j].x1 - l[i].x2); f[i][1] = min(f[i][1], tmp); } } //right if(l[i].x1 <= l[j].x2 && l[i].x2 >= l[j].x2 && l[j].h - l[i].h <= mx) { flag = true; for(k = j + 1; k < i && flag; ++k) { if(l[k].x1 <= l[j].x2 && l[k].x2 >= l[j].x2) {flag = false; break;} } if(flag && f[j][1] != inf) { tmp = f[j][1] + l[j].h - l[i].h + iabs(l[j].x2 - l[i].x1); f[i][0] = min(f[i][0], tmp); tmp = f[j][1] + l[j].h - l[i].h + iabs(l[j].x2 - l[i].x2); f[i][1] = min(f[i][1], tmp); } } } } int ans = inf; for(i = 0; i <= n; ++i) { if(l[i].h <= mx) { //left flag = true; for(k = i + 1; k <= n; ++k) { if(l[k].x1 <= l[i].x1 && l[k].x2 >= l[i].x1) {flag = false; break;} } if(flag) { tmp = f[i][0] + l[i].h; ans = min(tmp, ans); } //right flag = true; for(k = i + 1; k <= n; ++k) { if(l[k].x1 < l[i].x2 && l[k].x2 > l[i].x2) {flag = false; break;} } if(flag) { ans = min(ans, f[i][1] + l[i].h); } } } printf("%d\n", ans); } return 0; }