康復計劃 Round 2: Codeforces Lyft Level 5 Challenge 2018 - Final Round (Open Div. 1)

題目鏈接


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;
}

Codeforces - 1074B IntersectingSubtreesIntersecting Subtrees

解釋一下官方題解,首先從 L 的子樹任選一個結點,詢問一次得到同位置自己的結點編號 x

(1)然後再以這個編號 x 作爲樹根 dfs or bfs 整棵樹,找到一個自己子樹的結點 y 就記錄下來,然後再
(2)詢問這個節點在 L 的樹上的位置。

爲什麼這樣做呢,首先兩棵樹結構相同,那麼(1)操作找到的自己的結點 y ,是有可能和 x 是在同一棵子樹上的(因爲他們之間連着一條簡單路徑),那麼就詢問這個結點在 L 樹上的位置是否是 L 的子樹上的結點就 ok, 如果是,這個結點就必然是自己子樹和 L 子樹的公共結點。

交互題很 newbie (:з)∠)

代碼:

#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, head[N], cnt, tag;
bool a[N], b[N];
struct Edge {
    int to, nex;
}edge[N << 1];

inline void AddEdge (int u, int v) {
    edge[++cnt].nex = head[u];
    edge[cnt].to = v;
    head[u] = cnt;
    edge[++cnt].nex = head[v];
    edge[cnt].to = u;
    head[v] = cnt;
}
void dfs (int u, int fa) {
    if (a[u]) {
        tag = u;
        return ;
    }
    for (int i = head[u]; i; i = edge[i].nex) {
        int v = edge[i].to;
        if (v != fa) {
            dfs(v, u);
        }
    }
}

int main() {
#ifdef purple_bro
    freopen("in.txt", "r", stdin);
//    freopen("out.txt","w",stdout);
#endif
    int T;
    scanf("%d", &T);

    for (;T--;) {
        mst(head, 0);
        mst(a, false);
        mst(b, false);
        cnt = 0;

        scanf("%d", &n);

        for (int i = 1; i < n; i++) {
            int u, v;
            scanf("%d%d", &u, &v);
            AddEdge(u, v);
        }

        int k, tmp;
        scanf("%d", &k);

        for (int i = 1; i <= k; i++) {
            scanf("%d", &tmp);
            a[tmp] = true;
        }

        scanf("%d", &k);

        for (int i = 1; i <= k; i++) {
            scanf("%d", &tmp);
            b[tmp] = true;
        }

        printf("B %d\n", tmp);
        fflush(stdout);
        scanf("%d", &tag);

        dfs(tag, 0);

        printf("A %d\n", tag);
        fflush(stdout);
        scanf("%d", &tmp);

        if (b[tmp]) printf("C %d\n", tag);
        else printf("C -1\n");
        fflush(stdout);
    }

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章