您的位置:首页 > 其它

【模拟赛】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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: