1. 程式人生 > 其它 >AtCoder Beginner Contest 220 A-F

AtCoder Beginner Contest 220 A-F

A

#include <iostream>

using namespace std;

int main() {
    int a, b, c;
    cin >> a >> b >> c;
    for(int i = 1; i <= 1000; i ++ ) {
        if(c * i >= a && c * i <= b) {
            cout << c * i ;
            return 0;
        }
        if(c * i > b) break;
    }
    cout << "-1";
    return 0;
    
    return 0;
}

B

#include <iostream>
#include <algorithm>
#include <cstring>

#define LL long long
using namespace std;

int main() {
    string a, b;
    int k; cin >> k >> a >> b;
    LL cnt1 = 0, cnt2 = 0;
    // cout << a << b << endl;
    reverse(a.begin(), a.end());
    reverse(b.begin(), b.end());
    LL res = 1;
    for(int i = 0; a[i]; i ++ ) {
        int p = a[i] - '0';
        cnt1 += p * res;
        res *= k;
    }
    res = 1;
    for(int i = 0; b[i]; i ++ ) {
        int p = b[i] - '0';
        cnt2 += p * res;
        res *= k;
    }
    // cout << cnt1 << ' ' << cnt2 << endl;
    cout << cnt1 * cnt2;
    
    
    
    return 0;
}

C

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>

#define LL long long
using namespace std;

int main() {
    int n; cin >> n;
    vector<int> a(n);
    LL ans = 0;
    for(int &x: a) {
        cin >> x;
        ans += x;
    }
    LL p; cin >> p; 

    LL res = p / ans * n;
    LL pp = 0;
    p %= ans;

    for(int i = 0; i < n; i ++ ) {
        pp += a[i];
        if(pp > p) {
            cout << res + i + 1 << endl;
            return 0;
        } 
    }

    
    
    
    return 0;
}

D

線性DP

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
#define pb push_back

#define mod(x) (x) % MOD
#define LL long long

using namespace std;

const int MOD = 998244353, N = 1e5 + 10;

LL cnt[10];
int n, a[N];


int main() {
    cin >> n;
    for(int i = 0; i < n; i ++ ) cin >> a[i];
    vector<LL> p(10, 0), q(10, 0);
    q[a[0]] = 1;
    for(int i = 1; i < n; i ++ ) {
        // p = q;
        for(int j = 0; j < 10; j ++ ) {
            p[j] = q[j] % MOD;
            q[j] = 0;
        }
        for(int j = 0; j < 10; j ++ ) {
            q[(j + a[i]) % 10] =  mod(q[(j + a[i]) % 10] + p[j]);
            q[(j * a[i]) % 10] = mod(q[(j * a[i]) % 10] + p[j]);
        }

    }
    for(int i = 0; i < 10; i ++ ) {
        cout << q[i] % MOD << endl;
    }
    
    
    return 0;
}

E

對於每個節點形成的鏈有兩種可能

  • 這個節點是上端點
  • 這個節點是中轉節點

    對於1號節點
  • 第一種有鏈:421、521、631、731
  • 第二種有鏈:213、4213、42137....

這樣列舉可以不重不漏的找出所有的長度固定的鏈
而且,對於每個節點第一種有\(2^{n+1}\)個(正向逆向要重複計數),第二種有\((d-1)*{2^{d-1}}\)
當然有的節點可能不存在那麼多,也就是當剩餘的層數不足d的時候,我們就需要一層一層的拓展
比如說往下擴充套件一層就多了 $2 * {2^{d-2}} $ 即 左邊的層數所具有的節點 * 右邊層數所具有的節點 永遠都是 \(2^{d-1}\)
因此還剩多少層我就就會加多少個 \(2^{d-1}\)

AC_CODE

#include <bits/stdc++.h>
#define mod(x) ((x) % MOD)
#define LL long long

using namespace std;

const int N = 2e6 + 10, MOD = 998244353;

LL num[N];


int main() {
    // pre
    num[0] = 1;
    for(int i = 1; i < N; i ++ ) 
        num[i] = mod(num[i - 1] * 2);
    LL ans = 0;
    LL n, d; cin >> n >> d;

    for(int i = 0; i < n; i ++ ) {
        LL cnt = num[i];
        LL mx = n - i - 1;
        if(mx >= d) {
            ans = mod(ans + mod(num[d + 1] * cnt)); // 求出以第i層的節點為 鏈的端點的所有個數
            ans = mod(ans + mod(num[d - 1] * mod((d - 1) * cnt)));// 求出以第i層的節點為 鏈的轉折點的所有個數
            //轉折過後必須向下轉折 可以不重不漏
        } else if(2 * mx >= d) {
            ans = mod(ans + mod(mod(num[d - 1] * cnt) * (2 * mx - d + 1)));
            //求出以第i層的節點為 鏈的轉折點的所有個數 因為不可以為 鏈的端點
        } else break;
    }
    cout << mod(ans) << endl;


    return 0;
}

F

思路

先求出以1號節點為起點,其他的點到1號點的距離,然後對於1號點子節點,我們再繼續求以這個點為起點的路徑長度的時候
我們可以把其他的點分為兩種

  • 一種是以此點為根的點
  • 一種不是以此點為根的點

對於第一種,每條路徑長度減去1就是我們想知道的路徑長度,第二種則需要加上1
整理一下會發現就是 ans[j] = ans[u] + (n - size(j)) - size(j); (u是j的根節點)
因此可以用樹形DP解決這個問題

AC_CODE

#include <iostream>
#include <cstring>
#define LL long long

using namespace std;

const int N = 2e5 + 10, M = N << 1;

int h[N], e[M], ne[M], idx;
int n;
LL ans[N], s[N];

void add(int a, int b) {
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx ++;
}

int dfs(int u, int fa, int cnt) {
    ans[1] += cnt;
    int res = 1;
    for(int i = h[u]; ~i; i = ne[i]) {
        int j = e[i];
        if(j == fa)
            continue;
        res += dfs(j, u, cnt + 1);
    } 
    s[u] = res;
    return res;
}

void dfs1(int u, int fa) {
    for(int i = h[u]; ~i; i = ne[i]) {
        int j = e[i];
        if(j == fa)
            continue;
        ans[j] = ans[u] + n - 2 * s[j];
        dfs1(j, u);
    }
}

int main() {
    memset(h, -1, sizeof h);
    scanf("%d", &n);
    for(int i = 1; i < n; i ++ ) {
        int u, v;
        scanf("%d%d", &u, &v);
        add(u, v); add(v, u);
    }
    dfs(1, -1, 0);
    dfs1(1, -1);
    for(int i = 1; i <= n; i ++ )
        printf("%lld\n", ans[i]);
    return 0;
}