A - Five Variables
找出哪个位置是0。
#include#include using namespace std; int a[5]; int main() { for (int i = 0; i < 5; i++) { cin >> a[i]; if (a[i] == 0) { cout << i + 1; return 0; } } return 0; }
B - Crane and Turtle
解方程
#include#include using namespace std; int x, y; int a, b; /* 2a + 2b = 2x; 2a + 4b = y; b = (y - 2x) / 2; */ int main() { cin >> x >> y; if (y < 2 * x) { puts("No"); } else { if ((y - 2 * x) % 2) { puts("No"); } else { b = (y - 2 * x) / 2; a = x - b; if (a < 0) puts("No"); else puts("Yes"); } } return 0; }
C - Forbidden List
用个桶维护一下
#include#include using namespace std; int x, n; int a[110], cnt[110]; int main() { cin >> x >> n; for (int i = 1; i <= n; i++) cin >> a[i], cnt[a[i]]++; int i = 0; while (1) { if (!cnt[x - i]) { cout << x - i; return 0; } else if (!cnt[x + i]) { cout << x + i; return 0; } else { i++; } } return 0; }
D - Not Divisible
从小到大排序,用前面筛掉后面。
#include#include #include using namespace std; int n, a[200010], ans, cnt[1000010], num[1000010]; int main() { cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; num[a[i]]++; } sort(a + 1, a + 1 + n); for (int i = 1; i <= n; i++) { if (num[a[i]] > 1) { cnt[a[i]]++; continue; } bool flag = 1; for (int j = 1; j * j <= a[i]; j++) { if (a[i] % j) continue; if (cnt[j]) { flag = 0; break; } if (cnt[a[i] / j]) { flag = 0; break; } } ans += flag; cnt[a[i]]++; } cout << ans; return 0; }
E - Smart Infants
每个幼儿园用一棵平衡树维护。最小值用线段树维护。
赛时我竟然忘记有STL这种东西然后大力手写了一遍。
#includeusing namespace std; const int N = 400010; namespace IO{ template void read(T &x) { T f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -1; for (x = 0; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template void write(T x) { if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template void print(T x) { if (x < 0) putchar('-'), x = -x; write(x); putchar('\n'); } } using namespace IO; struct Segment{ int val; }tr[N << 2]; int n, q; int a[N], b[N]; int rt[N], fa[N], ch[N][2]; int cnt[N], key[N]; int tot; inline int get(int x) { return ch[fa[x]][1] == x; } inline void rotate(int x) { int y = fa[x], z = fa[y], w = get(x); if (z) ch[z][ch[z][1] == y] = x; fa[x] = z; ch[y][w] = ch[x][w ^ 1], fa[ch[x][w ^ 1]] = y; ch[x][w ^ 1] = y, fa[y] = x; } inline void splay(int x, int id) { for (int y = fa[x]; fa[x]; rotate(x), y = fa[x]) { if (fa[y]) rotate(get(y) == get(x) ? y : x); } rt[id] = x; } inline void insert(int x, int id) { if (rt[id] == 0) { tot++; rt[id] = tot; ch[tot][0] = ch[tot][1] = 0; cnt[tot] = 1; key[tot] = x; return; } int cur = rt[id], f = 0; while (cur) { if (key[cur] == x) { cnt[cur]++; splay(cur, id); return; } f = cur; cur = ch[cur][x > key[cur]]; } cur = ++tot; key[cur] = x; cnt[cur] = 1; ch[cur][0] = ch[cur][1] = 0; fa[cur] = f; ch[f][x > key[f]] = cur; splay(cur, id); } inline void find_rank(int x, int id) { int cur = rt[id]; while (cur) { if (key[cur] > x) { cur = ch[cur][0]; } else { if (key[cur] == x) { splay(cur, id); } cur = ch[cur][1]; } } } inline int find_pre(int x, int id) { int cur = rt[id], ret = -0x3f3f3f3f; while (cur) { if (key[cur]< x) ret = cur, cur = ch[cur][1]; else cur = ch[cur][0]; } return ret; } inline void clear(int cur) { cnt[cur] = fa[cur] = key[cur] = ch[cur][0] = ch[cur][1] = 0; } inline void del(int x, int id) { find_rank(x, id); if (cnt[rt[id]] > 1) { cnt[rt[id]]--; return; } if (!ch[rt[id]][0] && !ch[rt[id]][1]) { clear(rt[id]); rt[id] = 0; } else if (!ch[rt[id]][0]) { int tmp = rt[id]; rt[id] = ch[rt[id]][1]; fa[rt[id]] = 0; clear(tmp); } else if (!ch[rt[id]][1]) { int tmp = rt[id]; rt[id] = ch[rt[id]][0]; fa[rt[id]] = 0; clear(tmp); } else { int newroot = find_pre(x, id); int oldroot = rt[id]; splay(newroot, id); fa[ch[oldroot][1]] = rt[id]; ch[rt[id]][1] = ch[oldroot][1]; clear(oldroot); } } inline int find_max(int id) { int cur = rt[id]; if (cur == 0) return 0x7f7f7f7f; while (ch[cur][1]) cur = ch[cur][1]; return key[cur]; } void build(int p, int l, int r) { if (l == r) { tr[p].val = find_max(l); return; } int mid = (l + r) >> 1; build(p << 1, l, mid); build(p << 1 | 1, mid + 1, r); tr[p].val = min(tr[p << 1].val, tr[p << 1 | 1].val); } void change(int p, int l, int r, int pos) { if (l == r) { tr[p].val = find_max(l); return; } int mid = (l + r) >> 1; if (pos <= mid) change(p << 1, l, mid, pos); else change(p << 1 | 1, mid + 1, r, pos); tr[p].val = min(tr[p << 1].val, tr[p << 1 | 1].val); } int main() { read(n); read(q); for (int i = 1; i <= n; i++) { read(a[i]); read(b[i]); insert(a[i], b[i]); } build(1, 1, 200000); for (int i = 1; i <= q; i++) { int c, d; read(c); read(d); del(a[c], b[c]); change(1, 1, 200000, b[c]); b[c] = d; insert(a[c], b[c]); change(1, 1, 200000, b[c]); print(tr[1].val); } return 0; }
F - Pond Skater
bfs,维护每个节点的最短距离。如果在扩展时发现到某个节点的最短距离小于当前节点的最短距离+1就break,保证了复杂度。
#includeusing namespace std; int n, m, k; int a1, a2, b1, b2; char c[1000010]; char s[1000010]; int dis[1000010]; struct node{ int x, y; }; queue q; int dx[4] = {0, 0, 1, -1}; int dy[4] = {1, -1, 0, 0}; int f(int x, int y) { return (x - 1) * m + y; } bool check(int x, int y) { if (x < 1 || x > n) return false; if (y < 1 || y > m) return false; if (c[(x - 1) * m + y] == '@') return false; return true; } int main() { memset(dis, 0x3f, sizeof(dis)); cin >> n >> m >> k; cin >> a1 >> b1 >> a2 >> b2; for (register int i = 1; i <= n; ++i) { scanf("%s", s + 1); for (register int j = 1; j <= m; ++j) { c[(i - 1) * m + j] = s[j]; } } q.push(node{a1, b1}); dis[(a1 - 1) * m + b1] = 0; while (!q.empty()) { node now = q.front(); q.pop(); int num = dis[f(now.x, now.y)] + 1; for (register int i = 0; i < 4; ++i) { int xx = now.x, yy = now.y; for (register int j = 1; j <= k; ++j) { xx += dx[i]; yy += dy[i]; if (!check(xx, yy) || dis[f(xx, yy)] < dis[f(now.x, now.y)] + 1) break; if (dis[f(xx, yy)] > num) { dis[f(xx, yy)] = num; q.push(node{xx, yy}); } } } } if (dis[f(a2, b2)] < 0x3f3f3f3f) cout << dis[f(a2, b2)]; else puts("-1"); return 0; }