第二场选拔赛
2017-04-03 23:20
288 查看
A
目测一道难题,十有八九我也不会。
B
思路:枚举圆。
PS:写几何的时候注意精度。
C
思路:首先枚举种类,然后用隔板法求组合数。
D
思路:贪心。优先选择价值大的,使用的时间尽量靠后。
E
思路:KMP即可。fail[i]表示第i位前面的最长匹配前缀和后缀。
F
思路:dp1[i]表示以a[i]结尾的最大区间和,dp2[i]表示以a[i]开头的最大区间和。
答案就是max1<=i+2<=n(dp1[i]+(maxi+2<=j<=ndp2[j]))
G
解法一:先二分最小的最大值Max,然后选择所有的不大于Max−1的元素,之后不够的话补上Max即可。
解法二:直接用堆去维护,最多入队2∗N个元素。
H
思路:∑ni=1a[i]>2∗max1<=i<=na[i]
I
水题不说了。
J
很神奇,答案就是把N反过来输出。
K
目测语文阅读理解题目。读懂可以AC
L
最多三个人,很多人看错题意了。随便写都可以过
M
模拟即可。
目测一道难题,十有八九我也不会。
B
思路:枚举圆。
PS:写几何的时候注意精度。
C
思路:首先枚举种类,然后用隔板法求组合数。
#include <bits/stdc++.h> using namespace std; typedef long long LL; LL C[30][30]; int main() { for(int i = 0; i <= 25; i++) { C[i][0] = 1; } for(int i = 1; i <= 25; i++) { for(int j = 1; j <= i; j++) { C[i][j] = C[i - 1][j - 1] + C[i - 1][j]; } } int n, k; scanf("%d%d", &n, &k); LL ans = 0; for(int i = 1; i <= min(n, k); i++) { ans += C [i] * C[k - 1][i - 1]; } printf("%lld\n", ans); return 0; }
D
思路:贪心。优先选择价值大的,使用的时间尽量靠后。
#include <bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int, int> pii; const int MAXN = 1e5 + 10; pii a[MAXN]; bool cmp(pii x, pii y) { return x.second != y.second ? x.second > y.second : x.first < y.first; } vector<int> G; int main() { int n; scanf("%d", &n); int MT = 0; for(int i = 1; i <= n; i++) { scanf("%d", &a[i].first); MT = max(MT, a[i].first); } G.clear(); for(int i = 1; i <= MT; i++) G.push_back(i); for(int i = 1; i <= n; i++) { scanf("%d", &a[i].second); } sort(a + 1, a + n + 1, cmp); int ans = 0; for(int i = 1; i <= n; i++) { if(G.size() == 0) continue; if(*G.begin() > a[i].first) continue; ans += a[i].second; vector<int> :: iterator it; it = G.end(); --it; if(*it <= a[i].first) { G.erase(it); } else { it = upper_bound(G.begin(), G.end(), a[i].first); G.erase(--it); } } printf("%d\n", ans); return 0; }
E
思路:KMP即可。fail[i]表示第i位前面的最长匹配前缀和后缀。
#include <bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int, int> pii; const int MAXN = 1e5 + 10; char str[MAXN]; int fail[MAXN]; void getfail(char *P) { fail[0] = 0; fail[1] = 0; for(int i = 1; P[i]; i++) { int j = fail[i]; while(j && P[i] != P[j]) { j = fail[j]; } fail[i + 1] = P[i] == P[j] ? j + 1 : 0; } } bool judge(int l1, int r1, int l2, int r2) { int j = 0; for(int i = l1; i <= r1; i++) { while(j && str[i] != str[l2 + j]) { j = fail[j]; } if(str[i] == str[l2 + j]) { j++; } if(j == r2 - l2 + 1) return true; } return false; } int main() { int t; scanf("%d", &t); while(t--) { scanf("%s", str); getfail(str); int len = strlen(str); int j = fail[len]; int ans = 0; while(j) { if(3 * j <= len && judge(j, len - j - 1, 0, j - 1)) { ans = j; break; } else { j = fail[j]; } } printf("%d\n", ans); } return 0; }
F
思路:dp1[i]表示以a[i]结尾的最大区间和,dp2[i]表示以a[i]开头的最大区间和。
答案就是max1<=i+2<=n(dp1[i]+(maxi+2<=j<=ndp2[j]))
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int MAXN = 5e5 + 10; const int INF = -1e8; int a[MAXN]; int dp1[MAXN], dp2[MAXN]; int Max[MAXN]; int main() { int n; scanf("%d", &n); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); } for(int i = 0; i <= n + 1; i++) { dp1[i] = dp2[i] = Max[i] = INF; } for(int i = 1; i <= n; i++) { dp1[i] = max(dp1[i - 1] + a[i], a[i]); } for(int i = n; i >= 1; i--) { dp2[i] = max(dp2[i + 1] + a[i], a[i]); Max[i] = max(Max[i + 1], dp2[i]); } int ans = INF; for(int i = 1; i <= n - 2; i++) { ans = max(dp1[i] + Max[i + 2], ans); } printf("%d\n", ans); return 0; }
G
解法一:先二分最小的最大值Max,然后选择所有的不大于Max−1的元素,之后不够的话补上Max即可。
解法二:直接用堆去维护,最多入队2∗N个元素。
#include <iostream> #include <bits/stdc++.h> using namespace std; typedef long long LL; const int MAXN = 1e5 + 10; int a[MAXN], b[MAXN]; int n; LL Work(int o) { LL ans = 0; for(int i = 1; i <= n; i++) { if(b[1] + a[i] > o) { break; } int pos = upper_bound(b + 1, b + n + 1, o - a[i]) - b - 1; ans += pos; } return ans; } int ans[MAXN], top; void Put(int o) { top = 0; for(int i = 1; i <= n; i++) { if(b[1] + a[i] > o) { break; } int pos = upper_bound(b + 1, b + n + 1, o - a[i]) - b - 1; for(int j = 1; j <= pos; j++) { ans[top++] = a[i] + b[j]; } } } int main() { scanf("%d", &n); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); } for(int i = 1; i <= n; i++) { scanf("%d", &b[i]); } sort(a + 1, a + n + 1); sort(b + 1, b + n + 1); int l = a[1] + b[1], r = a + b ; int Max; while(r >= l) { int mid = l + r >> 1; LL num = Work(mid); if(num >= 1LL * n) { Max = mid; r = mid - 1; } else { l = mid + 1; } } Put(Max - 1); int left = n - top; for(int i = 0; i < left; i++) { ans[top++] = Max; } sort(ans, ans + top); for(int i = 0; i < top; i++) { printf("%d\n", ans[i]); } return 0; }
H
思路:∑ni=1a[i]>2∗max1<=i<=na[i]
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int MAXN = 1e6 + 10; int a[MAXN]; int main() { int n; scanf("%d", &n); int ans = -1; for(int i = 0; i < n; i++) { scanf("%d", &a[i]); } int sum = 0; int Max = 0; for(int i = 0; i < n; i++) { sum += a[i]; Max = max(Max, a[i]); if(sum > 2 * Max) { ans = i + 1; break; } } printf("%d\n", ans); return 0; }
I
水题不说了。
J
很神奇,答案就是把N反过来输出。
K
目测语文阅读理解题目。读懂可以AC
L
最多三个人,很多人看错题意了。随便写都可以过
M
模拟即可。
#include <bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int, int> pii; const int MAXN = 1e3 + 10; char str[MAXN]; int num[30]; int main() { int n; scanf("%d", &n); scanf("%s", str); for(int i = 0; i < 26; i++) num[i] = 0; for(int i = 0; str[i]; i++) { num[str[i] - 'a']++; } int ans = 0; for(int i = 0; i < 26; i++) { while(num[i]) { num[i]--; for(int j = i + 1; j < 26; j++) { if(num[j]) { num[j]--; } else { break; } } ans++; } } printf("%d\n", ans); return 0; }
相关文章推荐
- hnust队内选拔赛第二场 杀伤力(二维完全背包)
- hnust队内选拔赛第二场 杀伤力(二维完全背包)
- 省赛选拔赛——个人赛第二场
- 中南大学2016年校队选拔赛第二场Problem F
- 湖南工业大学个人选拔赛第二场 解题报告
- 湖南工业大学个人选拔赛第二场 解题报告
- 中南大学2016年校队选拔赛第二场Problem A
- 湖南工业大学个人选拔赛第二场 解题报告
- 湖南工业大学个人选拔赛第二场 解题报告
- 20130820 【南华大学 ACM】 个人选拔赛第二场 【A . BAKA】
- 20130820 【南华大学 ACM】 个人选拔赛第二场 【B . SUME】
- 20130820 【南华大学 ACM】 个人选拔赛第二场 【C . DOBRI】
- 省赛选拔赛——组队赛第二场
- 湖南中医药大学2017年集训队第二场选拔赛
- XDOJ省赛选拔赛第二场H题
- 中国崛起”是第二场“大跃进”神话!
- 赛题集锦—2008年百度之星程序设计大赛初赛第二场题
- 2010校内选拔赛获奖情况(陈年往事了……)
- 东北大学第七届大学生数学建模竞赛暨2010年全国大学生数学建模竞赛校内选拔赛试题
- HDOJ1087 Super Jumping! Jumping! Jumping!【逆推】----武科大ACM暑期集训队选拔赛6题