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\n", ans); return 0; }