• AtCoder Beginner Contest 157


    AtCoder Beginner Contest 157

    B

    (and,not,or) 这些关键字比较好打

    这题加个标记数组就好

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 110;
    int g[N][N],b[N],n;
    bool appear[N][N];
    int main() {
        ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
        for(int i = 0;i < 3; ++i)
            for(int j = 0;j < 3; ++j)
                cin >> g[i][j];
        cin >> n;
        for(int i = 0;i < n; ++i) {
            cin >> b[i];
        }
        for(int i = 0;i < 3; ++i) {
            for(int j = 0;j < 3; ++j) {
                for(int k = 0;k < n; ++k) {
                    if(b[k] == g[i][j]) appear[i][j] = 1;
                }
            }
        }
        bool f = 0;
        for(int i = 0;i < 3; ++i) {
            if(appear[i][0] and appear[i][1] and appear[i][2]) f = 1;
            if(appear[0][i] and appear[1][i] and appear[2][i]) f = 1;
        }
        if(appear[0][0] and appear[1][1] and appear[2][2]) f = 1;
        if(appear[0][2] and appear[1][1] and appear[2][0]) f = 1;
        if(f) cout << "Yes";
        else cout << "No";
    
        return 0;
    }
    

    C

    细节太多,有点坑,一定要多考虑边界情况

    n == 1 and m == 0

    n == 1 and m == 1

    还有首位不能是 0,只能补 1

    #include <bits/stdc++.h>
    using namespace std;
    int a[5];
    int main() {
        ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
        int n,m,c,s;
        cin >> n >> m;
        memset(a,-1,sizeof a);
        if(n == 1 and m == 0) {
            cout << 0;
            return 0;
        }
        for(int i = 0;i < m; ++i) {
            cin >> c >> s;
            if(a[c] == -1) {
                a[c] = s;
            }
            else if(a[c] != s) {
                cout << "-1";
                return 0;
            }
        }
        if(a[1] == 0 and n > 1) {
            cout << -1;
            return 0;
        }
        if(a[1] == -1) a[1] = 1;
        for(int i = 1;i <= n; ++i) {
            if(a[i] == -1) cout << 0;
            else cout << a[i]; 
        }
        return 0;
    }
    

    D

    带权并查集

    有n 个人,m对朋友关系,k对封锁关系(黑名单),问你每个人有多少个候选朋友

    要求候选朋友在同一个朋友圈内,且两人无直接的联系

    候选朋友的数量= 间接朋友的数量 - 不可能是候选朋友的数量 - 自己

    ans 记录不可能是候选朋友的数量 其中包括,黑名单的人 和 自己的朋友数量。

    size 记录整个连通块一共有多少人

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e5 + 10;
    int f[N],size[N],ans[N],n,m,k;
    int find(int x) {
        return x == f[x] ? x : f[x] = find(f[x]);
    }
    void merge(int x,int y) {
        int xx = find(x);
        int yy = find(y);
        if(xx != yy) {
            f[xx] = yy;
            size[yy] += size[xx];
        }
    }
    int main() {
        ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
        cin >> n >> m >> k;
        for(int i = 1;i <= n; ++i) f[i] = i,size[i] = 1;
        int x,y;
        while(m --) {
            cin >> x >> y;
            ans[x] ++,ans[y] ++;// 把自己给计算上
            merge(x,y);
        }
        while(k --) {
            cin >> x >> y;
            if(find(x) == find(y)) {// 在同一个朋友圈内,才算黑名单
                ans[x] ++;
                ans[y] ++;
            }
        }
        for(int i = 1;i <= n; ++i) {
            cout << size[find(i)] - ans[i] - 1 <<' ';
        }
        return 0;
    }
    

    E

    线段树,树状数组

    有一串字符,我们可以执行两种操作:

    1、替换某个位置的字符

    2、查询某一段区间不同字符的个数

    用26颗树来维护区间信息

    #include <bits/stdc++.h>
    using namespace std;
    #define endl '
    '
    const int N = 5e5 + 10;
    char s[N];
    int tr[30][N];
    int n,q,op;
    int lowbit(int x) {
        return x & -x;
    }
    void update(int x,int v,int a[]) {
        for(int i = x;i <= n;i += lowbit(i)) a[i] += v;
        // 在第x个位置更新 树a,每个自低向上+1,代表该字符出现的位置
    }
    int query(int x,int a[]) {
        int res = 0;
        for(int i = x;i >= 1;i -= lowbit(i)) {
            res += a[i];
        }
        // 在1 - x 这个区间,该字符出现的次数,肯定要在该字符的树上查询,自顶向下
        return res;
    }
    int main() {
        ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
        cin >> n >> s >> q;
        for(int i = 0;i < n; ++i) update(i + 1,1,tr[s[i] - 'a']);
        while(q --) {
            cin >> op;
            if(op == 1) {
                int i;
                char c;
                cin >> i >> c;
                // 先把原来这个区间全部减去 1
                update(i,-1,tr[s[i - 1] - 'a']);
                s[i - 1] = c;// 修改字符串
                update(i,1,tr[c - 'a']);// 修改区间内的信息
            }
            else {
                int l,r,cnt = 0;
                cin >> l >> r;
                for(int i = 0;i < 26; ++i) {
                    if(query(r,tr[i]) - query(l - 1,tr[i]) > 0) cnt ++;
                }
                cout << cnt << endl;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    多任务GUI窗口系统(类window,有源码,支持汉字显示、顶层、非矩形和透明窗口)gicell源码
    怎样判断treeview当前节点为treeview显示出来的第一个节点和最后一个节点?
    用 dbgrid 或 dbgrideh 如何让所显示数据自动滚动
    vue路由懒加载及组件懒加载
    vue 中使用rem布局
    纯css实现移动端横向滑动列表&&overflow:atuo;隐藏滚动条
    分布式一致性算法Raft
    HDU_1753 大明A+B
    POJ——3630 Phone List
    HDU_2647 Reward (拓扑排序)
  • 原文地址:https://www.cnblogs.com/lukelmouse/p/12491341.html
Copyright © 2020-2023  润新知