1. 程式人生 > 實用技巧 >AtCoder Beginner Contest 187

AtCoder Beginner Contest 187

AtCoder Beginner Contest 187

A - Large Digits

Solution

#include <iostream>
#include <algorithm>
using namespace std;

inline int get(int x)
{
    int ans = 0;
    while(x) {
        ans += x % 10;
        x /= 10;
    }
    return ans;
}

int main()
{
    int a, b;
    cin >> a >> b;
    cout << max(get(a), get(b)) << endl;
    return 0;
}
B - Gentle Pairs

Solution

#include <iostream>
#include <algorithm>
using namespace std;

inline bool cmp(pair<int, int> x, pair<int, int> y)
{
    int up = x.second - y.second;
    int dw = x.first - y.first;
    if(dw < 0) dw = -dw, up = -up;
    return up <= dw && up >= -dw;
}

const int maxn = 1111;

pair<int, int> arr[maxn];

int main()
{
    int n;
    cin >> n;
    for(int i = 0; i < n; ++i) cin >> arr[i].first >> arr[i].second;
    int ans = 0;
    for(int i = 0; i < n; ++i) {
        for(int j = i + 1; j < n; ++j) {
            if(cmp(arr[i], arr[j])) ans++;
        }
    }
    cout << ans << endl;
    return 0;
}
C - 1-SAT

Solution

用集合分類記錄帶感嘆號和不帶歎號的字串判斷是否存在匹配即可。

#include <iostream>
#include <set>
#include <algorithm>
#include <string>
using namespace std;

set<string> b1, b2;

char str[22];

int main()
{
    int n; cin >> n;
    bool fl = false;
    string ans = "";
    for(int i = 0; i < n; ++i) {
        cin >> str;
        if(str[0] == '!') {
            string mid(str + 1);
            if(b1.count(mid)) fl = true, ans = mid;
            b2.insert(mid);
        }
        else {
            string mid(str);
            if(b2.count(mid)) fl = true, ans = mid;
            b1.insert(mid);
        }
    }
    cout << (fl ? ans : "satisfiable") << endl;
    return 0;
}
D - Choose Me

Solution

Takahashi每去一個town都會獲得一定的votes並且會導致Aoki失去一些votes,具體為:

\[Votes_A-=A_i\\ Votes_B+=A_i+B_i \]

這樣導致兩人的votes差值為\(2*A_i+B_i\),因此將城鎮按照\(2*A_i+B_i\)的大小排序,從大到小處理即可

#include <iostream>
#include <algorithm>
using namespace std;

typedef long long ll;

const int maxn = 211111;

struct town
{
    ll A, B;
    bool operator < (const town &x) const {
        if(this->A * 2 + this->B == x.A * 2 + x.B) return this->A > x.A;
        return this->A * 2 + this->B > x.A * 2 + x.B;
    }
} arr[maxn];

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int n; cin >> n;
    ll a = 0, b = 0;
    for(int i = 0; i < n; ++i) {
        cin >> arr[i].A >> arr[i].B;
        a += arr[i].A;
    }
    sort(arr, arr + n);
    int num = 0;
    while(a >= b && num < n) {
        a -= arr[num].A;
        b += arr[num].A + arr[num].B;
        num++;
    }
    cout << num << endl;
    return 0;
}

此處,我嘗試用pair和cmp函式去排序,超時了=_=

E - Through Path

Solution

對於一條邊ab,若從a出發不經過b則a可到達除以b為根的子樹外的所有點,因此每次的值更新都會涉及要麼以a為根的子樹,要麼全樹減去以b為根的子樹,而對於全樹可以將每次的值的變化歸結到根節點上,之後一次遞推得出每個點的權,總結處理方式就是:(以從a出發不經過b為例)

  • 若b為a的父節點,則只對a為根的子樹加x,此時加到根a上即可
  • 若b不為a的父節點,則對整個樹的根節點加x,以b為根的子樹不能加x,所以此時減去x以抵消根的影響
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;

typedef long long ll;

const int maxn = 211111;

struct edge
{
    int a, b;
} eg[maxn];
int fa[maxn], vis[maxn], n;
ll val[maxn];
vector<ll> mp[maxn];

void dfs(int be)
{
    for(auto k : mp[be]) {
        if(vis[k]) continue;
        fa[k] = be;
        vis[k] = 1;
        dfs(k);
    }
    return;
}

void vdfs(int be)
{
    for(auto k : mp[be]) {
        if(vis[k]) continue;
        val[k] += val[be];
        vis[k] = 1;
        vdfs(k);
    }
    return;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n - 1; ++i) {
        cin >> eg[i].a >> eg[i].b;
        mp[eg[i].a].push_back(eg[i].b);
        mp[eg[i].b].push_back(eg[i].a);
    }
    memset(val, 0, sizeof(val));
    memset(vis, 0, sizeof(vis));
    vis[1] = 1;
    dfs(1);
    // for(int i = 1; i <= n; ++i) cout << "fa:" << fa[i] << endl;
    int q; cin >> q;
    while(q--) {
        int t, e, x; cin >> t >> e >> x;
        if(t == 1) {
            if(fa[eg[e].a] == eg[e].b) val[eg[e].a] += x;
            else val[1] += x, val[eg[e].b] -= x;
        }
        else {
            if(fa[eg[e].b] == eg[e].a) val[eg[e].b] += x;
            else val[1] += x, val[eg[e].a] -= x;
        }
    }
    memset(vis, 0, sizeof(vis));
    vis[1] = 1;
    vdfs(1);
    for(int i = 1; i <= n; ++i) {
        cout << val[i] << endl;
    }
    return 0;
}