1. 程式人生 > 其它 >AtCoder Beginner Contest 240 題解

AtCoder Beginner Contest 240 題解

目錄

A - Edge Checker

題目大意:

給個1 - 10 數字圍成一個圈,給你兩個數問你是否相鄰

int main (){
    IOS
    int a, b; cin >> a >> b;
    if (abs (a - b) == 1){
        cout << "Yes" << endl;
    }
    else if (a == 10 && b == 1 || a == 1 && b == 10) {
        cout << "Yes" << endl;
    }
    else cout << "No" << endl;
}

B - Count Distinct Integers

題目大意;

給一個數組,問你出現了多少不同的數字。(丟 set 裡就行)

int main (){
    IOS
    set <int> s;
    int n; cin >> n;
    for (int i = 1 ; i <= n ; i ++){
        int x; cin >> x;
        s.insert(x);
    }
    cout << s.size () << endl;
    return 0;
}

C - Jumping Takahashi

題目大意:

給定目的點 x, 跳躍 n 次,每次可以從 a, b 中選擇一個數跳躍一定的距離。問從起點 0 開始,能否恰好跳躍到 x 點。

分析:

暴力列舉每一次選 a 或者 b, 時間複雜度 \(O (2^n)\) , 顯然不行。考慮用 \(dp[i][j]\)去表示前 i 次跳躍後,是否能到達 j 點。

時間複雜度 \(O (nx)\) ,可以用滾動優化掉一維,但是懶得搞了qwq。

int f[105][10005];
int main (){
    IOS
    int n, x; cin >> n >> x;
    f[0][0] = 1;
    for (int i = 1 ; i <= n ; i ++){
        int a, b; cin >> a >> b;
        for (int j = 0 ; j <= 10000 - a ; j ++){
            if (f[i - 1][j])
            f[i][j + a] = f[i - 1][j];       
        }
        for (int j = 0 ; j <= 10000 - b ; j ++){
            if (f[i - 1][j])
            f[i][j + b] = f[i - 1][j];       
        }
    }
    if (f[n][x]){
        cout << "Yes" << endl;
    }
    else cout << "No" << endl;
    return 0;
}

D - Strange Balls

題目大意:

類似於 “祖瑪” 的遊戲,一個一個往桶裡新增小球,當 小球的編號與連續個數相同時,這部分小球會被消掉。求出每次新增小球后桶中小球個數。

分析:

用兩個棧去維護即可,一個棧維護個數,一個棧維護桶內小球的情況,然後模擬輸出即可。(一開始以為連續球必然會消去,wa了一發)

#include<bits/stdc++.h>
#define ll long long
#define INF 0x7f7f7f7f //2139062143
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define Equ(a,b) (fabs((a)-(b))<eps)
#define More(a,b) (((a)-(b))>(eps))
#define x first
#define y second
using namespace std;
const int N=1e6+7;
const double eps=1e-6;
const int mod=1e9+7;
int a[N];
int main (){
    IOS
    int t; cin >> t;
    stack <int> s, c;
    int now = 0, cnt = 0;
    while (t --){
        int n; cin >> n;
        if (s.empty()){
            s.push(n);
            now = n; cnt ++;
        }
        else {
            if (s.top () == n){
                if (cnt == n - 1){
                    while (s.size () > 0 && s.top () == n) s.pop();
                    if (s.empty()) now = 0, cnt = 0;
                    else{
                        if (c.empty()) cnt = 0;
                        else {
                            cnt = c.top(); c.pop();
                        }
                        n = s.top ();
                    }
                }
                else {
                    s.push(n);
                    cnt ++;
                }
            }
            else {
                s.push(n);
                c.push(cnt);
                now = n, cnt = 1;
            }
        }
        cout << s.size () << endl;
    }
    return 0;
}

E - Ranges on Tree

題目大意:

給一顆根節點為 1 的樹,每個節點有一個集合 \(S_i\) , 表示以該節點為根節點的子樹包含的節點數。要求給樹上的所有節點,分配一個區間,使得節點之間的區間關係和 \(S_i\) 之間的關係一致。輸出分配情況,同時使得所有區間的最右端最小。(用盡可能小的數去分配)

例如: 如果節點2 和節點 3 的子樹沒有交集,那麼為這兩個節點分配的區間的交集也應當為空集。如果節點 1 的子樹包含節點 2 的子樹,那麼區間 1 也應當包含 區間 2。

分析:

顯然可以看出,根節點 1 包含所有其他節點, 那麼根節點的區間一定是最大的。又可以看出,每個葉子節點一定是相互獨立的,所以要為每個葉子節點分配一個值。所以,根節點的長度為樹中葉子節點的個數。按每顆子樹的葉子節點數分配區間即可。

題目不難想,題意有點難讀,我讀了n個錯誤題意 ,比賽中實現得比較複雜,第一遍 dfs 求 每棵樹的葉子節點個數,第二遍 dfs 賦值。

#include<bits/stdc++.h>
#define ll long long
#define INF 0x7f7f7f7f //2139062143
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define Equ(a,b) (fabs((a)-(b))<eps)
#define More(a,b) (((a)-(b))>(eps))
#define x first
#define y second
using namespace std;
const int N=3e5+7;
const double eps=1e-6;
const int mod=1e9+7;
vector <int> a[N];
int cnt = 0;
bool st[N];
int d[N];
struct node{
    int l, r;
};
node ans[N];
int dfs (int u){
    bool flag = 0;
    for (auto i : a[u]){
        if (!st[i]){
            flag = 1;
            st[i] = 1;
            d[u] += dfs(i);
            st[i] = 0;
        }
    }
    if (flag)
        return d[u];
    d[u] = 1;
    return d[u];
}
void dfs2 (int u, int l){
    int loc = l;
    ans[u].l = l, ans[u].r = l + d[u] - 1;
    for (auto i : a[u]){
        if (!st[i]){
            st[i] = 1;
            dfs2 (i, loc);
            loc += d[i];
            st[i] = 0;
        }
    }
}
int main (){
    IOS
    int n; cin >> n;
    for (int i = 1 ; i < n ; i ++){
        int u, v; cin >> u >> v;
        a[u].push_back(v);
        a[v].push_back(u);
    }
    st[1] = 1;
    dfs(1);
    memset (st, 0, sizeof st);
    st[1] = 1;
    dfs2 (1, 1);
    for (int i = 1 ; i <= n ; i ++){
        cout << ans[i].l << ' ' << ans[i].r << endl;
    }
    return 0;
}

F - Sum Sum Max

待補