【模拟赛】qbxt金秋冲刺训练营杯NOIP模拟赛第一场总结
2017-09-20 21:16
471 查看
前言
虽然是赛后自己测 但也是完完整整的打了一遍模拟赛 断断续续牵扯了两天半的精力先链接一下题目
D1T1天天去哪吃 优质的模拟
D1T2天天和树tree 树的直径 深搜
D1T3摆摊 线段树
D2T1天天寄快递 贪心
D2T2天天和不可描述 字符串 栈
D2T3罪犯分组 状压DP
拿到题之后抱着必胜的决心去浏览了一下每一个题(真的只是浏览)大约用了1分钟吧
先看D1的题 哇T1这个式子是什么完了看不懂T1就要挂了?然后仔细看了一下题意好像可以模拟 然后T2是一个关于树的题 找离一条链最远的点且距离要尽量远?是不是要找最长子树最短的树根再找离它第二远的点?这不是树的重心嘛 T3一瞅感觉有点像区间DP。。不可做。。
然后是D2 T1看不懂啊感觉D2的题好难 T2扫了一眼感觉很水吧从两头往中间搜或者是一个变形的括号匹配? T3简直关押罪犯的既视感不过读了题感觉和并查集半毛前关系没有 而且牵扯到“最少”一定是DP吧 本来我就不会DP 按照qbxt的尿性肯定很难
于是有些惆怅 但还是开始做啦
D1
T1
细读之后发现我应该读懂题了qwq 但是感觉和任何算法都没有擦上边吧 吧 吧发现可以模拟 枚举从第3天开始的每一天 然后往前找n/2天看看到底应该吃什么 应该能够前60%
T2
oi群里闪过了一个词 直径。。嗯就是这样。。找树的直径我只会两遍DFS啊不会DP去求 那就两遍DFS 然后再找距离直径最远的点 但是 怎么找。。然后Zheng.HT大佬在旁边说他A了 真是太神了 他说他用了三遍dfs 这都能过?但我发现我貌似不会存直径 总之不方便再深搜 于是又遍历了一遍直径 应该差不多吧。。
T3
Zheng.HT帮忙翻译了一下题干 感觉挺简单的吧 长得比较像线段树 但我不会写啊 先写个暴力 发现暴力可以优化 感觉前50%的数据比较水的D1搞完
于是 期望:60 + 100 + 50 = 210 = dalao。。
然后 实际:60 + 20 + 70 = 150 = cai
t1的O(mn/2)跑了6个点 t3数据好水啊
然而唯一想到正解的t2 应该是跑直径的那边和后面的DFS写炸了吧 看了Zheng.HT的代码 确实是很裸的写了三遍DFS
D2
T1
读懂了题之后发现只要有一个公司不能提升k分就可以输出-23333333 所以先for循环看看在s次之内能不能满足条件 然后再排序一下 贪心思想把能拿最多分的先用掉 嗯这个想法应该很完美啊 后来听Zheng.HT说是正解T2
先翻书看了一眼括号匹配 于是就按括号匹配打了 发现在找到后括号准备把前括号和后括号之间的内容做前后调换的时候 可以从两头一块搞 减少时间复杂度 前80%的数据都小于100000 跑这些应该没问题T3
不会 发现每个测试点的n都告诉你了 而且很多情况都是可以判断的于是就
。
。
打表
D2搞完
T1知道正解思路就是这样之后自信了很多感觉 100 + 80 + ? = 180↑
交完之后发现是 30 + 80 + 20 = 130
T1蜜汁TLE 现在两个dalao帮我调题 程序都删的只剩下读入和输出了还是TLE 只想说tyvj真辣鸡啊 - -
T2还在意料之中 T3的表竟然拿了20分真是好。。开
fb54
心 后来得知Geng.C大佬搜索拿了90分。。正解状压DP
总结
最后总分为150 + 130 = 280 问了问Zheng.HT大佬 他应该拿了400分左右 这是不是山东省前三十的节奏啊 现在他每个题都改成满分了 太强了感觉自己码力确实太弱了 应该还是平常做题太少 但基本上把能拿的暴力分都拿到了吧 D2T1的TLE真不想说啥 唯一的遗憾就是D1T2了 还用了我最多的时间 后来问了一下这次比赛的讲师清华大学Zhang.RT 他说如果这套题是NOIP原题的话山东省省一稳一点得要接近350分吧 分数线就不好说了 sosad 今天离NOIP2017还有50天整啊 好好加油吧
ZHT的福利
附上Zheng.HT改后六个题AC的代码T1 =================================================================================== #include <cstdio> #define N 200001 #define max(x, y) ((x) > (y) ? (x) : (y)) int n, m; long long a , alp, bet; bool b ; int main() { int i, x; scanf("%d %d %d %d %d %d", &n, &m, &alp, &bet, &a[1], &a[2]); for(i = max(1, 3 - n / 2); i < 3; i++) b[a[i]] = 1; for(i = 3; i <= m; i++) { x = (alp * a[i - 1] % n + bet * a[i - 2] % n) % n; while(b[x]) { x++; if(x == n) x -= n; } a[i] = x; b[a[i]] = 1; if(i - n / 2 > 0) b[a[i - n / 2]] = 0; printf("%d ", a[i]); } return 0; } /* 3 4 7 11 2 0 */ T2 =================================================================================== #include <cstdio> #include <cstring> #include <iostream> #define N 100001 int n, cnt, k; int head , to[N << 1], next[N << 1], dis , pre ; bool vis , flag ; inline int read() { int x = 0, f = 1; char ch = getchar(); for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1; for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0'; return x * f; } inline void add(int x, int y) { to[cnt] = y; next[cnt] = head[x]; head[x] = cnt++; } inline void dfs(int u) { int i, v; vis[u] = 1; for(i = head[u]; ~i; i = next[i]) { v = to[i]; if(!vis[v]) { if(!flag[v]) dis[v] = dis[u] + 1; pre[v] = u; dfs(v); } } } inline void solve(int x) { int i; memset(vis, 0, sizeof(vis)); memset(dis, 0, sizeof(dis)); memset(pre, 0, sizeof(pre)); dfs(x); k = 1; for(i = 1; i <= n; i++) if(dis[i] > dis[k]) k = i; } int main() { int i, x, y; n = read(); memset(head, -1, sizeof(head)); for(i = 1; i < n; i++) { x = read(); y = read(); add(x, y); add(y, x); } solve(1); solve(k); for(i = k; i; i = pre[i]) flag[i] = 1; solve(k); printf("%d\n", dis[k]); return 0; } /* 8 1 2 2 3 1 4 4 5 1 6 6 7 7 8 */ T3 =================================================================================== #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 210001 #define root 1, 1, m #define ls now << 1, l, mid #define rs now << 1 | 1, mid + 1, r using namespace std; int n, m, q; int vis , next [3], a , g , mn[N << 2], ans ; struct node { int x, y, id; }p ; inline int read() { int x = 0, f = 1; char ch = getchar(); for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1; for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0'; return x * f; } inline void build(int now, int l, int r) { if(l == r) { mn[now] = g[l]; return; } int mid = (l + r) >> 1; build(ls); build(rs); } inline void update(int now, int l, int r, int x, int y, int d) { if(x <= l && r <= y) { mn[now] = min(mn[now], d); return; } int mid = (l + r) >> 1; if(x <= mid) update(ls, x, y, d); if(mid < y) update(rs, x, y, d); } inline int query(int now, int l, int r, int x) { if(l == r) return mn[now]; int mid = (l + r) >> 1; if(x <= mid) return min(mn[now], query(ls, x)); else return min(mn[now], query(rs, x)); } inline bool cmp(node x, node y) { return x.x < y.x; } int main() { int i, j = 1; n = read(); m = read(); q = read(); for(i = 1; i <= m; i++) { a[i] = read(); vis[a[i]] = 1; while(vis[j] == 1 || vis[j + 1] == 1) j++; g[i] = j; } memset(mn, 127, sizeof(mn)); build(root); for(i = 1; i <= n; i++) vis[i] = m + 1; for(i = m; i >= 1; i--) { next[i][1] = vis[a[i]]; next[i][0] = vis[a[i] - 1]; next[i][2] = vis[a[i] + 1]; vis[a[i]] = i; } for(i = 1; i <= q; i++) { p[i].id = i; p[i].x = read(); p[i].y = read(); } sort(p + 1, p + q + 1, cmp); j = 1; for(i = 1; i <= q; i++) { for(; j < p[i].x && j <= m; j++) { if(a[j] < n && j + 1 <= min(next[j][1], next[j][2]) - 1) update(root, j + 1, min(next[j][1], next[j][2]) - 1, a[j]); if(a[j] > 1 && j + 1 <= min(next[j][1], next[j][0]) - 1) update(root, j + 1, min(next[j][1], next[j][0]) - 1, a[j] - 1); } ans[p[i].id] = query(root, p[i].y); } for(i = 1; i <= q; i++) if(ans[i] >= n) puts("-1 -1"); else printf("%d %d\n", ans[i], ans[i] + 1); return 0; } T4 =================================================================================== #include <cstdio> #include <iostream> #include <algorithm> #define N 200001 #define LL long long bool b ; LL a , ans; int n, m, s, k; struct node { int e, t; }p ; inline int read() { int x = 0, f = 1; char ch = getchar(); for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1; for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0'; return x * f; } inline bool cmp(node x, node y) { return x.t > y.t; } int main() { int i, j; n = read(); m = read(); s = read(); k = read(); for(i = 1; i <= m; i++) { p[i].e = read(); p[i].t = read(); } std::sort(p + 1, p + m + 1, cmp); for(i = 1; i <= m; i++) if(a[p[i].e] < k && s && p[i].t > 2) { s--; b[i] = 1; ans += p[i].t - 2; a[p[i].e] += p[i].t - 2; } for(i = 1; i <= n; i++) if(a[i] < k) { puts("-23333333"); return 0; } for(i = 1; i <= m; i++) if(!b[i] && s && p[i].t > 2) { s--; ans += p[i].t - 2; } printf("%lld\n", ans); return 0; } /* 2 5 4 22 1 1 1 40 2 25 2 30 2 0 */ T5 =================================================================================== #include <cstdio> #include <cstring> #define N 500001 int top, n; int sta , pos ; char s ; inline void solve(int x, int y, int d) { int i; for(i = x; i != y; i += d) { if(s[i] != '(' && s[i] != ')') putchar(s[i]); else { solve(pos[i] - d, i, d * -1); i = pos[i]; } } } int main() { int i; scanf("%s", s + 1); n = strlen(s + 1); for(i = 1; i <= n; i++) { if(s[i] == '(') sta[++top] = i; if(s[i] == ')') { pos[i] = sta[top]; pos[sta[top]] = i; top--; } } solve(1, n + 1, 1); return 0; } /* abc(def) abc(hello)(world)lcy()x(owq(zrt)) (owq(zrt)) (y(g(el)da)nis) */ T6 =================================================================================== #include <cstdio> #include <bitset> #include <cstring> #include <algorithm> #define N 100001 #define min(x, y) ((x) < (y) ? (x) : (y)) int n, m, k, cnt; int f , s ; std::bitset <20> map[20], S, tmp; //集合为i的罪犯最少能分成几组 inline int read() { int x = 0, f = 1; char ch = getchar(); for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1; for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0'; return x * f; } inline void dfs(int now, int t) { int i; s[++cnt] = S.to_ulong(); for(i = now; i < n; i++) { tmp = S & map[i]; if(t + tmp.count() > k) continue; S[i] = 1; dfs(i + 1, t + tmp.count()); S[i] = 0; } } int main() { int i, j, x, y; n = read(); m = read(); k = read(); for(i = 1; i <= m; i++) { x = read() - 1; y = read() - 1; map[x][y] = map[y][x] = 1; } dfs(0, 0); std::sort(s + 1, s + cnt + 1); memset(f, 127, sizeof(f)); f[0] = 0; for(i = 1; i < (1 << n); i++) for(j = 1; s[j] <= i && j <= cnt; j++) if((i & s[j]) == s[j]) f[i] = min(f[i], f[i ^ s[j]] + 1); printf("%d\n", f[(1 << n) - 1]); return 0; } /* 3 3 1 1 2 2 3 1 3 */
COYG
相关文章推荐
- 【模拟赛】qbxt金秋冲刺训练营杯NOIP模拟赛第二场D1
- GDOI冲刺训练模拟赛第一套总结
- GDOI冲刺训练模拟赛第二套总结
- GDOI冲刺训练模拟赛第四套总结
- GDOI模拟赛round 1(4.11~13)训练总结
- GDOI冲刺训练模拟赛第三套总结
- PKUSC 模拟赛 day1 下午总结
- 第二次冲刺个人工作总结03
- 第一冲刺阶段 工作总结 04
- 2017.3.25【NOIP提高组】模拟赛B组 总结
- 【分享总结】导师训练之高效学习
- 团队冲刺第一阶段个人工作总结4
- 数据结构专题训练及总结
- 第一冲刺阶段工作总结04
- 20151006重庆市NOIP模拟赛总结
- 第二次冲刺个人工作总结04
- 第一次冲刺总结
- 11.1模拟赛总结
- 2018寒假训练第一场——吃鸡跑毒篇
- 20171009模拟赛总结