AtCoder Beginner Contest 170题解

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;
}
A

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;
}
B

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;
}
C

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;
}
D

E - Smart Infants

每个幼儿园用一棵平衡树维护。最小值用线段树维护。

赛时我竟然忘记有STL这种东西然后大力手写了一遍。

#include 
using 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;
}
E

F - Pond Skater

bfs,维护每个节点的最短距离。如果在扩展时发现到某个节点的最短距离小于当前节点的最短距离+1就break,保证了复杂度。

#include 
using 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;
}
F

 

你可能感兴趣的:(AtCoder Beginner Contest 170题解)