Codeforces Round #529 (Div. 3)错过上分记

Codeforces Round #529 (Div. 3)错过上分记

前言

这场比赛的题真的简单,除了E题奇奇怪怪的前后缀和。

A

读原字符,挑出里面的字符输出即可。

B

排个序,分类讨论两种情况马上完事。

C

先贪心地用最少的次数把这个数分解掉,如果要求次数当然无解。

如果多的话一定有解,因为你可以一直分解,除非全是1的情况。

D

我本来以为是什么欧拉回路,其实就是无脑的建图。

一个点可以有两个点选择,要与前面不矛盾即可。

E

E题后面都不会做了。

这道题要有4个数组:

  • int数组s1:一个前缀和,读到左括号+1,读到右括号-1。
  • int数组s2:一个后缀和,读到右括号+1,读到左括号-1。
  • bool数组b1:判断左边是否合法。
  • bool数组b2:判断右边是否合法。

还是看代码吧:

#include<cstdio>

const int maxn = 1000005;
char ch[maxn];
int n;
int s1[maxn], s2[maxn];
bool b1[maxn], b2[maxn];

int main() {
    scanf("%d", &n);
    scanf("%s", ch + 1);
    for(int i = 1; i <= n; i++) {
        s1[i] = s1[i - 1] + (ch[i] == '(' ? 1 : -1);
        if(s1[i] >= 0) b1[i] = true;
        else break;
    }
    for(int i = n; i >= 1; i--) {
        s2[i] = s2[i + 1] + (ch[i] == ')' ? 1 : -1);
        if(s2[i] >= 0) b2[i] = true;
        else break;
    }
    int ans = 0;
    b1[0] = b1[n + 1] = b2[0] = b2[n + 1] = true;
    for(int i = 1; i <= n; i++) {
        if(b1[i - 1] && b2[i + 1]) {
            if(ch[i] == '(') {
                if(s1[i - 1] - 1 == s2[i + 1]) ans++;
            } else if(ch[i] == ')') {
                if(s1[i - 1] + 1 == s2[i + 1]) ans++;
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}

F

F题其实比E题简单。

贪心的思想:从最小点权的点相连,每次的代价都是最小。

暴力建出这些边,然后跑一个最小生成树即可。

个人感觉还是挺优美的,把边数特别多的省得只剩下\(n\)阶。

代码:

#include<iostream>
#include<algorithm>
using std::cin;
using std::cout;
using std::endl;
#define ll long long
const ll maxn = 200005;
struct Edge {
    ll from, to, weight;
} s[maxn << 2];
ll tot;
struct Nodes {
    ll val, idx;
} a[maxn];
ll fa[maxn];
ll n, m;

ll find(ll x) {
    if(fa[x] == x) return x;
    return fa[x] = find(fa[x]); 
}
bool cmp(Nodes A, Nodes B) {
    return A.val < B.val;
}
bool cmp1(Edge A, Edge B) {
    return A.weight < B.weight;
}
void add(ll u, ll v, ll w) {
    s[++tot] = (Edge){u, v, w};
}
int main()
{
    cin >> n >> m;
    for(ll i = 1; i <= n; i++) {
        cin >> a[i].val; a[i].idx = i;
    }
    while(m--) {
        ll u, v, w; cin >> u >> v >> w;
        add(u, v, w);
    }
    std::sort(a + 1, a + n + 1, cmp);
    for(ll i = 2; i <= n; i++) {
        add(a[i].idx, a[1].idx, a[1].val + a[i].val);
    }
    std::sort(s + 1, s + tot + 1, cmp1);
    for(ll i = 1; i <= n; i++) fa[i] = i;
    ll cost = 0;
    for(ll i = 1; i <= tot; i++) {
        ll u = find(s[i].from), v = find(s[i].to);
        if(u == v) continue;
        fa[v] = u;
        cost += s[i].weight;
    }
    cout << cost << endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Garen-Wang/p/10324566.html