2017 Multi-University Training Contest
来源:互联网 发布:阿里云 微信小程序 编辑:程序博客网 时间:2024/06/04 00:57
这场我实在是补不动…..
HDU - 6085 - Rikka with Candies(bitset优化)
题意:
给若干个k的查询,输出
思路:
我们枚举从大到小枚举k,也就是说从for(int i = 0; i < a.size(); i++) ans += cnt[a[i]-k];
。所以对于每一个枚举到的k,都应该对他的倍数x进行cnt[x]++操作。
以上应该是暴力的做法,但是显然是会T的,不过由于题目要求的是mod2意义下的答案,所以可以用bitset进行优化。怎么优化呢,首先用一个bitset,ai,表示a数组有哪些数字。然后用一个bitset,bj,起到cnt数组的效果,只需要翻转对应位即可,因为mod2意义下的加法和它是等价的。统计答案的时候只需要(ai >> k) & bj).count() & 1。ai右移k,即-k,&上bj并count,即看有哪些数字满足
#include <bits/stdc++.h>using namespace std;const int maxn = 50000 + 5;int b[maxn], ans[maxn];bitset<maxn>ai, bj;int main(){ int T; scanf("%d", &T); while(T--) { ai.reset(), bj.reset(); int n, m, k; scanf("%d%d%d", &n, &m, &k); for(int i = 0; i < n; i++) { int x; scanf("%d", &x); ai.set(x); } for(int i = 0; i < m; i++) scanf("%d", &b[i]); sort(b, b + m); int bMax = b[m - 1]; int cnt = m - 1; for(int i = bMax; i >= 0; i--) { ans[i] = ((ai >> i) & bj).count() & 1; if(cnt >= 0 && b[cnt] >= i) { for(int j = 0; j <= bMax; j += b[cnt]) bj.flip(j); cnt--; } } for(int i = 0; i < k; i++) { int x; scanf("%d", &x); printf("%d\n", ans[x]); } } return 0;}
F - Rikka with Graph HDU - 6090(找规律计数)
题意:
给你n个孤点,让你添加m条边(
思路:
显然可以发现,
当
#include <bits/stdc++.h>using namespace std;int main(){ int T; scanf("%d", &T); while(T--) { long long n, m; scanf("%lld%lld", &n, &m); m = min(m, n * (n - 1) / 2); if(m < n) { printf("%lld\n", n * n * (n - 1) - (2 * n - 2 + (m - 1) * (n - 2)) * m); } else { long long d = m - n + 1; m = n - 1; long long ans = (n * n * (n - 1) - (2 * n - 2 + (m - 1) * (n - 2)) * m) / 2; printf("%lld\n", (ans - d) * 2); } } return 0;}
H - Rikka with Subset HDU - 6092 (01背包逆过程)
题意:
有一个a数组 (
思路:
其实如果,倒过来就是一个01背包的问题。已知a数组,让你求解b数组。所以这题就是一个倒过来的01背包。复杂度别估计错了,进入while循环的次数只有n次。
#include <bits/stdc++.h>using namespace std;long long dp[10000 + 5];int main(){ int T; scanf("%d", &T); while(T--) { memset(dp, 0, sizeof(dp)); int n, m; scanf("%d%d", &n, &m); vector<long long>b; b.resize(m + 1); for(int i = 0; i <= m; i++) scanf("%lld", &b[i]); vector<int>ans; for(int i = 1; i <= m; i++) { int x = b[i] - dp[i]; while(x > 0) { ans.push_back(i); x--; for(int j = m - i; j >= 0; j--) { dp[j + i] += dp[j]; } dp[i]++; } } for(int i = 0; i < ans.size(); i++) { printf("%d%c", ans[i], i == ans.size() - 1 ? '\n' : ' '); } } return 0;}
K - Rikka with Competition HDU - 6095(water)
题意:
出n个数,进行n-1场比赛,每场比赛如果双方值差的绝对值大于k就大的数赢,否则都有可能赢,问最后最多多少人可能赢。
思路:
简单题,排个序,从大到小,找一条最长链:满足俩俩之差不超过k。就能通过第二个胜第一个,第三个胜第二个,…,这种策略来达到使得这条链上任意一个人获胜。输出长度即可。
#include <bits/stdc++.h>using namespace std;int a[100000 + 5];int main(){ int T; scanf("%d", &T); while(T--) { int n, k; scanf("%d%d", &n,&k); for(int i = 0; i < n; i++) scanf("%d", &a[i]); sort(a, a + n); int ans = 1; for(int i= n - 1; i >= 1; i--) { if(a[i] - k > a[ i - 1]) break; ans++; } printf("%d\n", ans); } return 0;}
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- #2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- #2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- ByteArrayOutputstream与FileOutputstream
- 游标的那些事
- C#索引器
- select函数源码简析
- Fuzz安全狗注入绕过
- 2017 Multi-University Training Contest
- AS自带模拟器 Your GPU driver information
- linux系统mysql数据库基本命令
- Cuckoo for Hashing--关于哈希表的练习
- 关于使用c# Sqlite的问题
- shell脚本--if判断(数字条件、字符串条件)
- 支付密码的效果
- java程序截屏
- Junit4单元测试 (一) 基本使用