1. 程式人生 > >康復計劃 Round 2: Codeforces Lyft Level 5 Challenge 2018

康復計劃 Round 2: Codeforces Lyft Level 5 Challenge 2018

題目連結

Codeforces - 1074A TheTowerisGoingHomeThe Tower is Going Home

簡單說下題意,就是戰車一開始是在左下角,戰車可以水平走和垂直走,然後有垂直的和水平的障礙,戰車可以把他移掉,問戰車能夠到達縱座標 1e91e9 處最少需要移掉多少障礙。

離散化 + 區間覆蓋,首先思考一下,當在右邊有更優解的時候,左邊這一塊間隔肯定不移掉障礙物,到達右邊間隔再移掉夾在中間的垂直障礙物,可以看到,我們就可以不用管那些在縱座標之下的障礙物,那麼這個地方就可以對 水平障礙物的左端點,縱座標

進行排序,這樣排之後那些縱座標比前面一個小的就可以丟棄,剩下的就進行區間覆蓋,因為座標很大,所以要離散化。

最後答案就是區間覆蓋的最小值,當然還要加上向右走移掉的障礙物。

程式碼:

#include <bits/stdc++.h>
#pragma GCC optimize "-O3"
#define mst(a,b) memset(a,b,sizeof(a))
#define ALL(x) x.begin(),x.end()
#define pii pair<int,int>
#define eps 1e-6
#define debug(a) cout << #a": " << a << endl;
#define eularMod(a, b) a < b ? a : a % b + b inline int lowbit(int x){ return x & -x; } const int N = 1e5 + 10; const int mod = (int) 998244353; const int INF = 0x3f3f3f3f; const long long LINF = (1LL << 62); typedef long long LL; typedef unsigned long long ULL; const double PI = acos(-1.0
); using namespace std; int n, m, a[N], v[N]; struct line { int L, R, Y; bool operator < (const line &t) const { if (L != t.L) return L < t.L; else return Y < t.Y; } }l[N]; int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); } a[++n] = 1000000000; sort(a + 1, a + 1 + n); for (int i = 1; i <= m; i++) { scanf("%d%d%d", &l[i].L, &l[i].R, &l[i].Y); l[i].L--; } sort(l + 1, l + m + 1); int pre = 0; for (int i = 1; i <= m; i++) { if (l[i].Y < pre) break; pre = l[i].Y; int pos1 = lower_bound(a, a + 1 + n, l[i].L) - a; int pos2 = lower_bound(a, a + 1 + n, l[i].R) - a; if (a[pos2] != l[i].R) pos2--; if (pos1 == pos2 || pos1 > pos2) continue; v[pos1]++; v[pos2]--; } int ans = INF; int tmp = 0; int sum = 0; for (int i = 0; i < n; i++) { sum += v[i]; ans = min(ans, sum + tmp); tmp++; } printf("%d\n", ans); return 0; }