「赛后总结」AtCoder Beginner Contest 177
题意 & 题解
A.Don't be late
题意:
给你路程,时间限制,速度,问你能不能在时间限制内走路程那么远。
题解:
数学题?物理题?签到题!
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
int a, b, c;
int main() {
std::cin >> a >> b >> c;
double t = (a * 1.0) / (c * 1.0);
if (t - b * 1.0 >= 1e-8) puts("No");
else puts("Yes");
return 0;
}
B.Substring
题意:
给你两个字符串 \(s,t\),问你最少更改 \(s\) 几次能使得 \(t\) 是 \(s\) 的字串。
题解:
因为字符串长度小于 \(1000\) 直接暴力枚举 \(t\) 出现在 \(s\) 的什么位置。
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
int min(int a, int b) { return a < b ? a : b; }
int ans = 2147483647;
std::string s, t;
int main() {
std::cin >> s >> t;
int len1 = s.length(), len2 = t.length();
for (int i = 0; i < len1; ++i) {
if (i + len2 - 1 >= len1) break;
int p = i, sum = 0;
for (int j = 0; j < len2; ++j, ++p) {
if (s[p] == t[j]) ++sum;
}
ans = min(ans, len2 - sum);
}
std::cout << ans << '\n';
return 0;
}
C.Sum of product of pairs
题意:
求 \(\sum\limits_{i = 1}^{N - 1}\sum\limits_{j = i + 1} ^ {N} A_i A_j\)
题解:
数学题,化简一下就成了 \(\sum\limits_{i = 1}^{N - 1}A_i\sum\limits_{j = i + 1} ^ {N} A_j\),后面用前缀和维护一下。
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define MAXN 200001
#define int long long
const int mod = 1000000007;
int n, ans, a[MAXN], sum[MAXN];
signed main() {
scanf("%lld", &n);
for (int i = 1; i <= n; ++i) {
scanf("%lld", &a[i]);
sum[i] = (1ll * sum[i - 1] + 1ll * a[i]) % mod;
}
for (int i = 1; i < n; ++i) {
ans = (ans + 1ll * a[i] * ((sum[n] - sum[i] + mod) % mod) % mod) % mod;
}
std::cout << ans << '\n';
return 0;
}
D.Friends
题意:
给你一些人之间的朋友关系,可以互相传递,问你最少分成多少组使得每一组都没有两个人是朋友。
题解:
并查集。最大的连通块的大小就是答案。
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define MAXN 200001
int max(int a, int b) { return a > b ? a : b; }
int n, m, fa[MAXN], size[MAXN];
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
void Union(int x, int y) {
int rootx = find(x), rooty = find(y);
if (rootx == rooty) return;
if (size[rootx] > size[rooty]) {
fa[rooty] = rootx;
size[rootx] += size[rooty];
}
else {
fa[rootx] = rooty;
size[rooty] += size[rootx];
}
}
int main() {
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; ++i) fa[i] = i, size[i] = 1;
for (int i = 1, u, v; i <= m; ++i) {
scanf("%d %d", &u, &v);
Union(u, v);
}
int ans = 0;
for (int i = 1; i <= n; ++i) {
if (fa[i] == i) ans = max(ans, size[i]);
}
std::cout << ans << '\n';
return 0;
}
E.Coprime
题意:
给定一个序列 \(a\),判断是否满足 \(\forall \ (i,j)\),\(1 \le i < j \le n\),\(\gcd(a_i,a_j) = 1\) 或者 \(\gcd(a_1,a_2,\dots,a_n) = 1\)。
题解:
如果一些数的最大公约数不等于 \(1\) 表示这些书具有相同的质因子。将每个 \(a_i\) 质因数分解,并统计质因数出现的次数。
普通的对每个数进行质因数分解的话时间复杂度是 \(O(n\sqrt n)\) 的。
如果先筛出每个数最小的质因子在进行分解时间复杂的是 \(O(nlogn)\) 的。
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 1000001
bool prime[M], used[M];
int n, a[M], d[M], cnt[M];
void isprime() {
for (int i = 2; i < M; ++i) {
if (!prime[i]) {
d[i] = i;
int j = i + i;
while (j < M) {
prime[j] = true;
if (!d[j]) d[j] = i;
j += i;
}
}
}
}
void div(int x) {
int temp = x;
while (temp != 1) {
if (!used[d[temp]]) {
++cnt[d[temp]];
used[d[temp]] = true;
}
temp /= d[temp];
}
while (x != 1) {
used[d[x]] = false;
x /= d[x];
}
}
int main() {
scanf("%d", &n); isprime();
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
for (int i = 1; i <= n; ++i) div(a[i]);
bool flag1 = true, flag2 = true;
for (int i = 2; i < M; ++i) {
if (!prime[i]) {
if (cnt[i] > 1) flag1 = false;
if (cnt[i] == n) flag2 = false;
}
}
if (flag1) puts("pairwise coprime");
else if (flag2) puts("setwise coprime");
else puts("not coprime");
return 0;
}
F.I hate Shortest Path Problem
题意:
咕咕咕
题解:
咕咕咕
rating & 总结
- 上一场 ABC 是 174 有好长时间没打了。。
- C 题取模因为负数的原因 WA 了两发/kk
- D 题因为最后统计答案的时候把 n 写成了 m (什么sb)WA了一发。
- EF 都没思路,真是个垃圾。
- 掉分小技巧:马上就要开始考试了,你发现你的电脑时间不准然后去校准你就会比别人晚 10min 左右开题???电脑问题还是 AT 问题?