Atcoder Beginner Contest 226

A - Round decimals

这道题就是让你对输入的数进行四舍五入,但是我一开始用%.0f输出,结果给我WA了。

然后队友告诉我,%.0f并不是四舍五入,而是四舍六入五成双。

也就是说88.5因为是偶数,所以就会变成88;89.5的话就会变成90。

所以输出round(input)就好了

B - Counting Arrays

给你N个长度不一的数组,问你不重复的数组有几个。

我写的是map<vector<int>. int> 。我以为会T的但是并没有。

现在好好算算。

暴力比较的复杂度是N2的,是因为最坏情况是每次只有一个数,之后每次都跟前面n-1个比较,于是就到n2了

但是如果我们用map的话,比较的时候应该是len * logn之后要比较n次所以是 len*n*logn。

但是这样是不对的,因为总长度也只有2e5,所以最坏的情况时取到 len = sqrt(2e5)

意味着每次都需要跟logn个长度为len的字符串进行比较。但是总数又跟len相关,所以总数会变成n / sqrt(len)

于是复杂度就变成了 n / sqrt(2e5) * sqrt(2e5) * log(n/sqrt(2e5)) = 1e6+

可过。

C - Martial artist

随便写了个倒着的BFS就过去了。

不过好像有更快的写法,就是倒着for 一遍就好了。

每次把需要的打上标记,因为他保证了需要技能点都会小于当前的标号。

之后统计以下哪些被打上标记即可。

D - Teleportation

这题感觉没啥难度,就是处理出 n2 * 2个方位,记得要除以正的gcd,之后放到map/set里去重即可。

E - Just one

这道题一开始没读出来有且有一条出边的条件。读出来了之后,这道题就比较简单了。

首先我们要知道有且仅有一条出边该如何转化,也就是说每个点都会有只有一条边属于这个点。

我们知道,一条边能带来2个度,那么我们就可以得出2 * n = sum(du)的结论。

于是对每个没访问过的点进行DFS,如果结束了不满足2 * n = sum(du)的条件,答案就是0

否则就是满足条件的块数的2的幂次,pow(2, cnt)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int inf = 0x3f3f3f3f; ///1061109567
const int maxn = 2e5 + 10;
const int mod = 998244353;

vector<int> G[maxn];
int vis[maxn];
int ns, dus;
void DFS(int u) {
    vis[u] = 1;

    ns ++;
    dus += G[u].size();

    for (auto v : G[u]) {
        if (vis[v] == 0) DFS(v);
    }
    return ;
}

int main() {
    int n, m; scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; ++ i) {
        int u, v; scanf("%d%d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    ll ans = 1;
    for (int i = 1; i <= n; ++ i) {
        if (vis[i] == 0) {
            DFS(i);
            if (ns * 2 != dus) ans = 0;
            ans = ans * 2 % mod;
        }
    }
    printf("%lld
", ans);

    return 0;
}
原文地址:https://www.cnblogs.com/Vikyanite/p/15523383.html