#include<algorithm> #include<iostream> #include<map> #include<string> usingnamespace std; longlong ans, l[114514], r[114514], c[32]; string s; // map<string, long long> memory; // long long count(string str) // { // if (memory.find(str) != memory.end()) // return memory[str]; // long long res = 0, a[256]; // for (long long i = 0; i < 256; i++) // a[i] = 0; // for (long long i = 0; i < str.length(); i++) // a[str[i]]++; // for (long long i = 0; i < 256; i++) // if (a[i] == 1) // res++; // memory[str] = res; // return res; // } // O(n^2logn) -> O(n) signedmain() { ios::sync_with_stdio(false); cin >> s; for (longlong i = 0; i < 32; i++) c[i] = -1; for (longlong i = 0; i < s.length(); i++) l[i] = i - c[(longlong)(s[i] - 'a')], c[(longlong)(s[i] - 'a')] = i; // find pre char for (longlong i = 0; i <= 26; i++) c[i] = s.length(); for (longlong i = s.length() - 1; i >= 0; i--) r[i] = c[(longlong)(s[i] - 'a')] - i, c[(longlong)(s[i] - 'a')] = i; for (longlong i = 0; i < s.length(); i++) ans += l[i] * r[i]; // for (long long i = 2; i <= s.length(); i++) // for (long long j = 0; j < s.length() - i + 1; j++) // { // string subs = s.substr(j, i); // sort(subs.begin(), subs.end()); // ans += count(subs); // } cout << ans; return0; }
B-成绩分析
直接贴代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#include<algorithm> #include<cstdio> #include<iostream> usingnamespace std; intmain() { int n, sum = 0, minn = 114514, maxx = -1919810; cin >> n; for (int i = 1; i <= n; i++) { int a; cin >> a; maxx = max(maxx, a); minn = min(minn, a); sum += a; } printf("%d\n%d\n%.2lf", maxx, minn, sum * 1.0 / n); return0; }
C-画中漂流
这道题一看就像 DP,再一看确实是的,找一下它的状态转移方程。由于距离大于等于 D 就寄了,所以变量应该找时间和体力,列关于时间i和体力j的转移方程。当前状态应该等于上一状态用体力和不用体力的方案数之和,即
F(i,j)=F(i−1,j)+F(i−1,j+1)
然后我们又知道时间为 0 时只要游了就不会似,所以初始化ans[0][m]=1。注意,每次还需要检查似了没,也就是step=D+(m-j)-(i-m+j)。(花一点体力就游 1 米,共 D 米)
输出ans[t][0],也就是时间为 t 时,用完 m 点体力的总方案数,别忘了long long和取模。代码如下
找规律,分奇偶层,每一层的数字填充方向奇数层从右到左,偶数层从左到右,第 n 行第 n 列的数位于第 2n-1 层。对于第 n 行第 n 列的数,所在的层数为 2n-1 层,该层的起始数字 S(m)=1+(2n+1)(n−1),其中 m 为层数 2n-1,而第 n 行第 n 列的数是该层的第 n 个位置,因此其值为 S(m)−(n−1),即1+2n(n−1)。代入 n=20:1+2×20×19=1+760=761
#include<bits/stdc++.h> usingnamespace std; intgcd(int a, int b) { if (b == 0) return a; returngcd(b, a % b); } inteuler_ex(int a)// o.o { int cnt = 0; for (int n = 1; n <= 2020; n++) if (gcd(n, a) == 1) //&& ((n > a) ? (n / a * a == n) : (a / n * n == a))) cnt++; return cnt; } intmain() { int ans = 0; for (int i = 1; i <= 2020; i++) ans += euler_ex(i); cout << ans; return0; }
End
A 题想完头就炸了…因为真的好久没写题,连 cpp 都很久没用过,一时间啥也想不起。甚至连开 vector、bitset 我都差点忘记怎么开了。很多高中时期会的优化技巧也忘干净了,然后一些基本算法我也感觉很陌生(说真的现在让我写个高精减法我都不一定能写出来,快排也是,并查集,堆,图之类的数据结构也不记得了)。如果出个图论我恐怕只会用邻接矩阵存。然后那天听说考 KMP,也不会。