A. 俄罗斯国旗

  • 直接模拟就好了
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    #define MAX 55
    int W[MAX], B[MAX], R[MAX];
    string mp[MAX];
    signed main() {
    IOS;
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
    cin >> mp[i];
    mp[i] = ' ' + mp[i];
    }
    for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
    W[i] += mp[i][j] != 'W';
    B[i] += mp[i][j] != 'B';
    R[i] += mp[i][j] != 'R';
    }
    W[i] += W[i - 1];
    B[i] += B[i - 1];
    R[i] += R[i - 1];
    }
    int ans = 1e9;
    for (int i = 1; i <= n; i++) {
    for (int j = i + 1; j < n; j++) {
    ans = min(ans, W[i] + B[j] - B[i] + R[n] - R[j]);
    }
    }
    cout << ans << endl;

    return 0;
    }

B. 被感染的二进制数

  • 模拟一下二进制乘法就好了
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    signed main()
    {
    IOS;
    string s;
    cin >> s;
    int n = s.size();
    s = ' ' + s;
    vector<int> a(11111, 0), b(11111, 0);
    for (int i = 1; i <= n; i++)
    b[i + 4] = a[i] = s[i] - '0';
    int op = 0;
    for (int i = n + 4, t = 0; i >= 0; i--)
    {
    a[i] += b[i] + op;
    op = a[i] / 2;
    a[i] %= 2;
    }
    for (int i = a[0] ? 0 : 1; i <= n + 4; i++)
    {
    cout << a[i];
    }

    return 0;
    }

C. 造篱笆

  • 因为h很小所以可以用DP的思路去实现一下
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    signed main()
    {
    IOS;
    int n;
    cin >> n;
    vector<int> v(n + 1);
    for (int i = 1; i <= n; i++)
    {
    cin >> v[i];
    }
    vector<int> h(4500), k(4500);
    int cnt = 0, mx = 0;
    for (int i = 1; i <= n; i++)
    {
    h[v[i]]++;
    }
    for (int i = 1; i <= 2000; i++)
    {
    for (int j = i; j <= 2000; j++)
    {
    if (h[i] == 0 || h[j] == 0)
    continue;
    if (i == j)
    {
    k[i + j] += h[i] / 2;
    continue;
    }
    k[i + j] += min(h[i], h[j]);
    }
    }
    for (int i = 1; i <= 4200; i++)
    {
    // cout << k[i] << ' ';
    mx = max(mx, k[i]);
    }
    for (int i = 1; i <= 4200; i++)
    {
    if (mx == k[i])
    {
    cnt++;
    }
    }
    cout << mx << ' ' << cnt << endl;

    return 0;
    }

D. 回文数字

  • 还是去模拟的去做
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    const int N = 1e5 + 10;

    string s;
    int a[N];

    void solve() {
    cin >> s;
    int n = s.size();
    s = "$" + s;

    for (int i = 1; i <= (n + 1) / 2; i ++ ){
    a[i] = a[n - i + 1] = s[i] - '0';
    }

    int ans = 0;
    for (int i = 1; i <= n; i ++ ) //大
    if (a[i] != s[i] - '0'){
    ans = a[i] > (s[i] - '0');
    break;
    }
    if (ans){
    for (int i = 1; i <= n; i ++ )
    cout << a[i] ;
    return ;
    }

    int j = (n + 1) / 2;
    while (j >= 1 && a[j] == 9){
    j --;
    }
    if (j == 0){
    //中间添加
    for (int i = 1; i <= n + 1; i ++ )
    cout << "01"[i == 1 || i == n + 1];
    }else{
    a[j] ++;
    for (int i = j + 1; i <= (n + 1) / 2; i ++ ) a[i] = 0;
    for (int i = 1; i <= n; i ++ )
    cout << (i <= (n + 1) / 2 ? a[i] : a[n - i + 1]);
    }
    }

    signed main() {
    IOS;
    int t = 1;
    // cin >> t;
    while (t--) {
    solve();
    }
    return 0;
    }

E. 礼物

  • 双端搜索就好了
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    #define MAX 35
    int a[MAX], b[MAX];
    int l;
    int n;
    vector<int> ans[MAX];
    int res = 1e18;
    void dfs1(int idx, int sum, int num) {
    if (idx == l + 1) {
    ans[num].push_back(sum);
    return ;
    }
    dfs1(idx + 1, sum + a[idx], num + 1);
    dfs1(idx + 1, sum - b[idx], num);
    }

    void get(int num, int sum) {
    for (auto tmp : ans[num]) {
    //cout << tmp << ' ' << sum << endl;
    res = min(res, abs(tmp + sum));
    }
    }
    void dfs2(int idx, int sum, int num) {
    if (idx == n + 1) {
    get((n + 1) / 2 - num, sum);
    get(n / 2 - num, sum);
    return ;
    }
    dfs2(idx + 1, sum + a[idx], num + 1);
    dfs2(idx + 1, sum - b[idx], num);
    }

    signed main() {
    IOS;
    cin >> n;
    l = (n + 1) / 2;
    for (int i = 1; i <= n; i++) {
    cin >> a[i];
    }
    for (int i = 1; i <= n; i++) {
    cin >> b[i];
    }
    dfs1(1, 0, 0);
    for (int i = 0; i <= n; i ++ ){
    sort(ans[i].begin(), ans[i].end());
    }
    dfs2(l + 1, 0, 0);
    cout << res << endl;
    return 0;
    }

F. 必经过点

  • 缩点模版 + 数学
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #define MAX 500005
    vector<int> G[MAX];
    int dfn[MAX], low[MAX], cnt, sz[MAX], n, m;
    int ans[MAX];
    void dfs(int u, int fa) {
    dfn[u] = low[u] = ++cnt;
    sz[u] = 1;
    int son = 0;
    for (auto v : G[u]) {
    if (v == fa) continue;
    if (dfn[v]) {
    low[u] = min(low[u], dfn[v]);
    } else {
    dfs(v, u);
    low[u] = min(low[u], low[v]);
    sz[u] += sz[v];
    if (dfn[u] <= low[v]) {
    ans[u] += son * (ll)sz[v];
    son += sz[v];
    }
    }
    }
    ans[u] += son * (ll)(n - 1 - son);
    }


    signed main() {
    IOS;
    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
    int u, v;
    cin >> u >> v;
    G[u].push_back(v); G[v].push_back(u);
    }
    dfs(1, 0);
    for (int i = 1; i <= n; i++) {
    cout << ((ans[i] -1 + n) << 1) << endl;
    }
    return 0;
    }