本文最后更新于:星期四, 二月 3日 2022, 9:15 晚上
A
题意
给定一个n , M A X P n, MAXP n , M A X P ,问在1 − M A X P 1-MAXP 1 − M A X P 范围内是否存在一个长度为n n n 的并且全部由素数组成的等差序列,优先找差值最大的,若有多个则找最大值最大的,若不存在则输出范围内最大素数
解法
素数筛出范围内所有质数,暴力判断每个差值是否存在即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 #include <bits/stdc++.h> using namespace std ;const int N = 2e5 + 10 ;int n, m, k;bool isPrime[N];int prime[N];void gao () { memset (isPrime, true , sizeof isPrime); for (int i = 2 ; i <= m; ++i) { if (isPrime[i]) { prime[++k] = i; } for (int j = 2 * i; j <= m; j += i) { isPrime[j] = false ; } } }int main () { ios::sync_with_stdio(false ); cin .tie(nullptr ), cout .tie(nullptr ); cin >> n >> m; gao(); for (int dif = 100000 ; dif >= 1 ; --dif) { for (int i = k; i >= n; --i) { if (prime[i] - (n - 1 ) * dif <= 0 ) break ; vector <int > v; v.push_back(prime[i]); int last = prime[i]; while (true ) { if (v.size() == n) { break ; } if (isPrime[last - dif]) { last = last - dif; v.push_back(last); } else { break ; } } if (v.size() == n) { reverse(v.begin(), v.end()); for (int o = 0 , len = v.size(); o < len; ++o) { cout << v[o] << " \n" [o == len - 1 ]; } return 0 ; } } } cout << prime[k] << endl ; return 0 ; }
B
题意
有n n n 个人,每个人有进出l a b lab l a b 的申请时间,同一时间内只能有一个人在l a b lab l a b 中,问最多同意几个申请
解法
典型区间贪心,然而忘了怎么写
于是d p dp d p 冲过去了
d p dp d p 做法:
将开始时间排序,然后简单d p dp d p …只有当当前开始时间比上一次结束时间迟的时候才可以转移
区间贪心做法:
待补
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 #include <bits/stdc++.h> using namespace std ;const int N = 2e5 + 10 ;struct E { int begin, end; E() {} E(int begin, int end): begin(begin), end(end) {} bool operator < (const E &other) const { if (begin != other.begin) { return begin < other.begin; } else { return end < other.end; } } }a[N];int n;int f[N];int main () { scanf ("%d" , &n); for (int i = 1 ; i <= n; ++i) { int h1, h2, m1, m2, s1, s2; scanf ("%d:%d:%d %d:%d:%d" , &h1, &m1, &s1, &h2, &m2, &s2); int t1 = h1 * 60 * 60 + m1 * 60 + s1; int t2 = h2 * 60 * 60 + m2 * 60 + s2; a[i] = E(t1, t2); } sort(a + 1 , a + 1 + n); int res = 0 ; for (int i = 1 ; i <= n; ++i) { f[i] = max(1 , f[i]); for (int j = i + 1 ; j <= n; ++j) { if (a[j].begin >= a[i].end) { f[j] = max(f[j], f[i] + 1 ); } } res = max(res, f[i]); } printf ("%d\n" , res); return 0 ; }
C
题意
要求维护一个h e a p heap h e a p ,然后一堆无脑询问
思路
按照题意模拟即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 #include <bits/stdc++.h> using namespace std ;const int N = 2e5 + 10 ;int n, q;int a[N];void build (int x) { for (int i = x; i > 1 ; i /= 2 ) { int fa = i / 2 ; if (a[i] > a[fa]) { swap(a[i], a[fa]); } else { break ; } } }int find (int x) { for (int i = 1 ; i <= n; ++i) { if (a[i] == x) return i; } return -1 ; }int main () { ios::sync_with_stdio(false ); cin .tie(nullptr ), cout .tie(nullptr ); cin >> n >> q; for (int i = 1 ; i <= n; ++i) { cin >> a[i]; build(i); } int x, y; string s; for (int cas = 1 ; cas <= q; ++cas) { cin >> x >> s; if (s == "and" ) { cin >> y; cin >> s >> s; x = find(x), y = find(y); if (x == -1 || y == -1 ) { cout << 0 ; continue ; } if (x / 2 == y / 2 ) { cout << 1 ; } else { cout << 0 ; } } else { cin >> s >> s; if (s == "root" ) { x = find(x); if (x == 1 ) cout << 1 ; else cout << 0 ; } else if (s == "parent" ) { cin >> s >> y; x = find(x), y = find(y); if (x == -1 || y == -1 ) { cout << 0 ; continue ; } if (x == y / 2 ) { cout << 1 ; } else { cout << 0 ; } } else if (s == "left" ) { cin >> s >> s >> y; x = find(x), y = find(y); if (x == -1 || y == -1 ) { cout << 0 ; continue ; } if (y * 2 == x) { cout << 1 ; } else { cout << 0 ; } } else { cin >> s >> s >> y; x = find(x), y = find(y); if (x == -1 || y == -1 ) { cout << 0 ; continue ; } if (y * 2 + 1 == x) { cout << 1 ; } else { cout << 0 ; } } } } cout << endl ; return 0 ; }
D
题意
给出一张n + 1 n+1 n + 1 个点的无向图,从0 0 0 出发,每次找最近的点,如果有多个则找下标最小的,询问访问顺序和路径长度,如果无法走完所有的点则输出无法访问的点
思路
F l o y d Floyd F l o y d 之后d f s dfs d f s 即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 #include <bits/stdc++.h> using namespace std ;const int N = 2e2 + 10 ;const int INF = 0x3f3f3f3f ;struct Edge { int v, w; Edge() {} Edge(int v, int w): v(v), w(w) {} bool operator < (const Edge &other) const { if (w != other.w) return w < other.w; else return v < other.v; } };int n, m;vector <int > v;bool vis[N];int res;int mp[N][N];vector <Edge> G[N];void Init () { memset (vis, 0 , sizeof vis); memset (mp, 0x3f , sizeof mp); for (int i = 0 ; i <= n; ++i) mp[i][i] = 0 ; }void Floyd () { for (int k = 0 ; k <= n; ++k) { for (int i = 0 ; i <= n; ++i) { for (int j = 0 ; j <= n; ++j) { mp[i][j] = min(mp[i][j], mp[i][k] + mp[k][j]); } } } for (int i = 0 ; i <= n; ++i) { for (int j = 0 ; j <= n; ++j) if (i != j && mp[i][j] != INF) { G[i].push_back(Edge(j, mp[i][j])); } sort(G[i].begin(), G[i].end()); } }void gao (int u) { vis[u] = true ; v.push_back(u); for (auto it : G[u]) { int v = it.v, w = it.w; if (vis[v]) continue ; res += w; gao(v); } }int main () { ios::sync_with_stdio(false ); cin .tie(nullptr ), cout .tie(nullptr ); cin >> n >> m; Init(); for (int i = 1 , u, v, w; i <= m; ++i) { cin >> u >> v >> w; mp[u][v] = w; mp[v][u] = w; } Floyd(); gao(0 ); for (int i = 0 , len = v.size(); i < len; ++i) { cout << v[i] << " \n" [i == len - 1 ]; } if (v.size() == n + 1 ) { cout << res << endl ; } else { vector <int > vec; for (int i = 0 ; i <= n; ++i) { if (!vis[i]) { vec.push_back(i); } } for (int i = 0 , len = vec.size(); i < len; ++i) { cout << vec[i] << " \n" [i == len - 1 ]; } } return 0 ; }