赞
踩
因为自己的大意马虎和迷之自信,还有一些其他原因。去年拿国一,又训练了一年反而退步到了国二。总之还是个人原因,不管为人还是处事,一定要谦虚谨慎,不断进取,自我反省。
答案
200/8 = 25
答案
1903
代码
先欧拉筛出所有质数,然后对每个数按位判断,注意素数标记数组要把 1 1 1 和 0 0 0 都设置为非素数。
#include <bits/stdc++.h> using namespace std; #define ENDL "\n" typedef long long ll; typedef pair<int, int> pii; const int Mod = 1e9 + 7; const int maxn = 3e7 + 10; vector<int> prime; bitset<maxn> vis; void euler() { vis.set(); vis[0] = 0; vis[1] = 0; for (int i = 2; i < maxn; i++) { if (vis[i]) prime.push_back(i); for (int j = 0; j < prime.size() && i * prime[j] < maxn; j++) { vis[i * prime[j]] = 0; if (i % prime[j] == 0) break; } } } bool check(int x) { while (x) { if (!vis[x % 10]) return 0; x /= 10; } return 1; } int main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int ans = 0; euler(); for (int i = 1; i <= 20210605; i++) { if (vis[i] && check(i)) ans++; } cout << ans << ENDL; return 0; }
答案
977
代码
模拟日期一天一天加。老是忘记闰年的判断,实际上只需要记住每四年为闰年,但是世纪年要模400为0才是闰年,例如1900年就不是闰年。
#include <bits/stdc++.h> using namespace std; #define ENDL "\n" typedef long long ll; typedef pair<int, int> pii; const int Mod = 1e9 + 7; const int maxn = 2e5 + 10; int run[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int ping[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int cal(int x) { int ans = 0; while (x) { ans += x % 10; x /= 10; } return ans; } bool check(int y, int m, int d) { int x = cal(y) + cal(m) + cal(d); int q = sqrt(x + 0.5); return q * q == x; } bool isRun(int y) { if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) return 1; return 0; } int main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int y = 2001, m = 1, d = 1, cnt = 0; while (1) { if (y == 2022) break; if (check(y, m, d)) cnt++; if (isRun(y)) { if (d == run[m]) { d = 1; if (m == 12) m = 1, y++; else m++; } else d++; } else { if (d == ping[m]) { d = 1; if (m == 12) m = 1, y++; else m++; } else d++; } } cout << cnt << ENDL; return 0; }
答案
2653631372
代码
这题实际上是一个DP,递归的想每个点的权值只和左右子树的节点个数有关,因此可以写记忆化搜索, d [ i ] = i n f , d [ 0 ] = 0 d[i] = inf,d[0] = 0 d[i]=inf,d[0]=0。
当前子树下需要放置 x x x 个节点,那么当前节点放一个,枚举左子树放置 i ( 0 ≤ i < x ) i(0 \leq i < x) i(0≤i<x) 个,那么右子树放置的个数为 x − 1 − i x - 1 - i x−1−i,状态转移方程为 d [ x ] = m i n ( d [ x ] , d [ x ] ∗ 2 + d [ x − 1 − i ] ∗ 3 + i ∗ i ∗ ( x − 1 − i ) d[x] = min(d[x], d[x] * 2 + d[x - 1 - i] * 3 + i*i*(x - 1 - i) d[x]=min(d[x],d[x]∗2+d[x−1−i]∗3+i∗i∗(x−1−i)。
时间复杂度 O ( n 2 ) O(n^2) O(n2)
#include <bits/stdc++.h> using namespace std; #define ENDL "\n" typedef long long ll; typedef pair<int, int> pii; const int Mod = 1e9 + 7; const ll INF = 1e18; const int maxn = 2e5 + 10; ll d[3000]; ll dfs(int x) { if (d[x] != INF) return d[x]; ll ans = d[x]; for (int i = 0; i < x; i++) { ans = min(ans, 1LL + dfs(i) * 2 + dfs(x - 1 - i) * 3 + 1LL * i * i * (x - 1 - i)); } return d[x] = ans; } int main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); for (int i = 1; i <= 2021; i++) d[i] = INF; cout << dfs(2021) << endl; return 0; }
代码
#include <bits/stdc++.h> using namespace std; #define ENDL "\n" typedef long long ll; typedef pair<int, int> pii; const int Mod = 1e9 + 7; const ll INF = 1e18; const int maxn = 2e5 + 10; int main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); char c; while (cin >> c) cout << (char) toupper(c); return 0; }
思路
根据前缀和得出区间之和为 s u m [ r ] − s u m [ l − 1 ] sum[r] - sum[l-1] sum[r]−sum[l−1]。
题目明显是分段来求的,具体来说是将序列看做 { 1 } , { 1 , 2 } , { 1 , 2 , 3 } , { 1 , 2 , 3 , 4 } , . . . \{1\},\{1,2\},\{1,2,3\}, \{1,2,3,4\},... {1},{1,2},{1,2,3},{1,2,3,4},...
其中每一块的长度刚好是 1 , 2 , 3 , 4... 1,2,3,4... 1,2,3,4...,而每一块的所有元素之和是 1 , 3 , 6 , 10... 1,3,6,10... 1,3,6,10...,每块元素之和的前缀和为 p r e [ i ] = { 1 , 4 , 10 , 20... } pre[i] = \{1,4,10,20...\} pre[i]={1,4,10,20...},这个前缀和的第 i i i 项刚好对应了组合数 C i + 2 3 C_{i + 2}^3 Ci+23。
因此思路就很明确了,二分确定前面有多少个完整的块,然后 O ( 1 ) O(1) O(1) 算出这些块的和,最后拿 n n n 减去前面块的元素个数,得到的一定是一个新的块中的从1开始的连续若干个自然数,根据等差数列公式 n ( n + 1 ) 2 \frac{n(n + 1)}{2} 2n(n+1)即可求出,累加上述二者即可。
代码
#include <bits/stdc++.h> using namespace std; #define ENDL "\n" typedef long long ll; typedef pair<int, int> pii; const int Mod = 1e9 + 7; const ll INF = 1e18; const int maxn = 2e5 + 10; ll cal1(ll n) { return n * (n + 1) * (n + 2) / 6; } ll cal2(ll n) { return n * (n + 1) / 2; } ll getSeg(ll n) { ll l = 1, r = 1e9, mid, ans; while (l <= r) { mid = (l + r) >> 1; if (cal2(mid) <= n) { ans = mid; l = mid + 1; } else r = mid - 1; } return ans; } ll solve(ll n) { if (n == 0) return 0; ll s = getSeg(n); return cal2(n - cal2(s)) + cal1(s); } int main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int T; ll l, r; cin >> T; while (T--) { cin >> l >> r; cout << solve(r) - solve(l - 1) << ENDL; } return 0; }
思路
正解目前不会,网上也没找到讲解,但是暴力能拿80%的分,首先随机01串打表发现对于长度为 n n n 的01串,其周期为大于等于它的最小的2的幂次。因此 n ≤ 1000 n \leq 1000 n≤1000时周期最大为1024,可以暴力。
代码
b i t s e t bitset bitset最右位下标为0。
#include <bits/stdc++.h> using namespace std; #define ENDL "\n" typedef long long ll; typedef pair<int, int> pii; const int Mod = 1e9 + 7; const ll INF = 1e18; const int maxn = 2e5 + 10; bitset<1005> a; map<string, bool> mp; string res[10005]; void table() { srand(time(0)); int n = rand() % 1000 + 1; string s = ""; for (int i = 0; i < n; i++) a[i] = rand() % 2, s += '0' + a[i]; mp[s] = 1; int T = 0; while (1) { T++; bitset<1005> b = a; b >>= 1; a ^= b; s = ""; for (int i = n - 1; i >= 0; i--) s += '0' + a[i]; if (mp.count(s)) break; } cout << n << " " << T << endl; } int main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); // table(); int n; ll t; string s = ""; cin >> n >> t; cin >> s; for (int i = n - 1, x, j = 0; i >= 0; i--, j++) { x = s[j] - '0'; if (x) a.set(i); } mp[s] = 1; int T = 0; while (1) { res[T++] = s; bitset<1005> b = a; b >>= 1; a ^= b; s = ""; for (int i = n - 1; i >= 0; i--) s += '0' + a[i]; if (mp.count(s)) break; } // cout << T << endl; t %= T; cout << res[t] << endl; return 0; }
思路
最裸的数位DP了。
代码
#include <bits/stdc++.h> using namespace std; #define ENDL "\n" typedef long long ll; typedef pair<int, int> pii; const int Mod = 1e9 + 7; const ll INF = 1e18; const int maxn = 2e5 + 10; ll d[105][55][2]; int digit[105]; int k; ll dfs(int pos, int sum, bool flag) { if (pos == 0) return sum == k; if (d[pos][sum][flag] != -1) return d[pos][sum][flag]; int up = flag ? digit[pos] : 1; ll ans = 0; for (int i = 0; i <= up; i++) { ans += dfs(pos - 1, sum + (i == 1), flag & (i == up)); } return d[pos][sum][flag] = ans; } ll solve(ll n) { int len = 0; while (n) { digit[++len] = n & 1; n /= 2; } memset(d, -1, sizeof d); return dfs(len, 0, 1); } int main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); ll n; cin >> n >> k; cout << solve(n) << endl; return 0; }
思路
暴力可拿20%
代码
#include <bits/stdc++.h> using namespace std; #define ENDL "\n" typedef long long ll; typedef pair<int, int> pii; const int Mod = 1e9 + 7; const ll INF = 1e18; const int maxn = 2e5 + 10; char s[maxn]; int n; int solve(int x) { stack<char> st; int ans = 0; for (int i = x; i <= n; i++) { if (s[i] == '(') st.push(s[i]); else { if (st.size()) st.pop(); else return ans; if (st.empty()) ans = i; } } return ans; } int main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int m; char ch; cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> ch; s[i] = ch; } int op, l, r; while (m--) { cin >> op; if (op == 1) { cin >> l >> r; for (int i = l; i <= r; i++) s[i] = (s[i] == '(' ? ')' : '('); } else { cin >> l; cout << solve(l) << ENDL; } } return 0; }
思路
根据异或的性质一个数异或它本身得0,可拿20%
代码
#include <bits/stdc++.h> using namespace std; #define ENDL "\n" typedef long long ll; typedef pair<int, int> pii; const int Mod = 1e9 + 7; const ll INF = 1e18; const int maxn = 2e5 + 10; bool check(int i, int j, int k) { int a[3]; a[0] = i, a[1] = j, a[2] = k; sort(a, a + 3); return a[0] + a[1] > a[2]; } int main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int T, n; cin >> T; while (T--) { cin >> n; int ans = 0; for (int i = 1; i <= n; i++) for (int j = 1, k; j <= n; j++) { k = i ^ j; if (1 <= k && k <= n && check(i, j, k)) { //cout << i << " " << j << " " << k << ENDL; ans++; } } cout << ans << ENDL; } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。