zoukankan      html  css  js  c++  java
  • AtCoder Regular Contest 80

    链接

    C. 4-adjacent

    给定序列$a_i$,询问是否存在一个排列,满足$a_{p[i]}* a_{p[i + 1]}$是4的倍数

    贪心构造

    首先把只是2的倍数的数拿出来,放在最右边

    前面把是1的倍数的数和是4的倍数的数交替放置即可

    之后随意判断即可

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    extern inline char gc() {
        static char RR[23456], *S = RR + 23333, *T = RR + 23333;
        if(S == T) fread(RR, 1, 23333, stdin), S = RR;
        return *S ++;
    }
    inline int read() {
        int p = 0, w = 1; char c = gc();
        while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }
        while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
        return p * w;
    }
    
    #define ri register int
    int n, n2, n4, flag;
    
    int main() {
        n = read();
        for(ri i = 1; i <= n; i ++) {
            int x = read();
            if(x % 4 == 0) n4 ++;
            else if(x % 2 == 0) n2 ++;
        }
        n -= n2;
        if(n & 1) {
            if(n2) flag = (n4 > n / 2);
            else flag = (n4 >= n / 2);
        }
        else flag = (n4 >= n / 2);
        if(flag) printf("Yes
    ");
        else printf("No
    ");
        return 0;
    }

    D.Grid Coloring

    对$R*W$的格子进行染色,需要使颜色$i$的出现次数为$c_i$

    且同一颜色形成联通块,询问是否可行并给出一组方案

    S形涂色即可

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    #define ri register int
    #define sid 105
    
    int H, W, n, id;
    int col[sid][sid], ord[sid * sid];
    
    int main() {
        scanf("%d%d%d", &H, &W, &n);
        for(ri i = 1; i <= n; i ++) {
            int x; scanf("%d", &x);
            while(x --) ord[++ id] = i;
        }
        id = 0;
        for(ri i = 1; i <= H; i ++)
        for(ri j = 1; j <= W; j ++)
        col[i][j] = ord[++ id];
        for(ri i = 2; i <= H; i += 2)
        reverse(col[i] + 1, col[i] + W + 1);
        for(ri i = 1; i <= H; i ++, printf("
    "))
        for(ri j = 1; j <= W; j ++)
        printf("%d ", col[i][j]);
        return 0;
    }

    E.Young Maids

    题意略复杂,直接看原题面吧...

    从前往后去贪心

    每次选择的一定是某个区间中的奇(偶)最小值后其后的偶(奇)最小值

    注意奇偶的判断即可

    复杂度$O(n log n)$

    一开始表示平衡树裸题,然后点开题解,还是打st表吧

    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    extern inline char gc() {
        static char RR[23456], *S = RR + 23333, *T = RR + 23333;
        if(S == T) fread(RR, 1, 23333, stdin), S = RR;
        return *S ++;
    }
    inline int read() {
        int p = 0, w = 1; char c = gc();
        while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }
        while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
        return p * w;
    }
    
    #define sid 200050
    #define inf 1e9
    #define ri register int
    
    int n;
    int bit[sid], l_g[sid];
    int st[sid][21][2], v[sid][2], arc[sid];
    
    void Init() {
        for(ri i = 0; i <= 30; i ++) bit[i] = 1 << i;
        for(ri i = 2; i <= n; i ++) l_g[i] = l_g[i >> 1] + 1;
        for(ri o = 0; o <= 1; o ++)
        for(ri i = 1; i <= n; i ++) st[i][0][o] = v[i][o];
        for(ri o = 0; o <= 1; o ++)
        for(ri j = 1; bit[j] <= n; j ++)
        for(ri i = 1; i + bit[j] - 1 <= n; i ++)
        st[i][j][o] = min(st[i][j - 1][o], st[i + bit[j - 1]][j - 1][o]);
    }
    
    inline int rmq(int l, int r, int o) {
        int lg = l_g[r - l + 1];
        return min(st[l][lg][o], st[r - bit[lg] + 1][lg][o]);
    }
    
    struct Seg {
        int v, l, r;
        friend bool operator < (Seg a, Seg b)
        { return a.v > b.v; }
    };
    priority_queue <Seg> q;
    
    int main() {
        n = read();
        for(ri i = 1; i <= n; i ++) {
            int w = (v[i][(i ^ 1) & 1] = read());
            v[i][i & 1] = inf; arc[w] = i;
        }
        Init();
        q.push({ rmq(1, n, 0), 1, n });
        while(!q.empty()) {
            Seg tmp = q.top(); q.pop();
            int w1 = tmp.v, pw1 = arc[w1];
            int w2 = rmq(pw1 + 1, tmp.r, pw1 & 1), pw2 = arc[w2];
            printf("%d %d ", w1, w2);
            if(tmp.l != pw1) q.push({ rmq(tmp.l, pw1 - 1, (tmp.l + 1) & 1), tmp.l, pw1 - 1 });
            if(pw1 + 1 != pw2) q.push({ rmq(pw1 + 1, pw2 - 1, pw1 & 1), pw1 + 1, pw2 - 1 });
            if(pw2 != tmp.r) q.push({ rmq(pw2 + 1, tmp.r, pw2 & 1), pw2 + 1, tmp.r });
        }
        return 0;
    }

    F.Prime Flip

    有$n$个位置的牌向上,

    每次可以选定一段长为$p$($p$为奇质数)的区间,翻转这个区间

    询问最少几次能使所有牌向下

    考虑构造新序列$e_i = [a_i = a_{i + 1}]$,$a_i$表示向上还是向下

    当$e_i$全部为0时,原序列全部向下

    那么,原题的区间操作转化为同时对两个点翻转

    两个点匹配有3种情况

    1.相差为奇质数,需要1次

    2.相差为偶数,需要2次

    3.否则,需要3次

    对于第一种情况,做二分图匹配

    第二种情况,讨论

    第三种情况,讨论

    对我而言是神题,不会做.....

    然而有一堆AK的神仙....

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    #define ri register int
    #define ssd 10000010
    #define sid 205
    
    int n, N = 1e7;
    int pr[ssd / 10], tot;
    int nj, no, js[sid], os[sid];
    bool nop[ssd], e[ssd];
    
    int tim, vis[sid], mat[sid];
    bool ex[sid][sid];
    
    inline void Init() {
        nop[1] = 1;
        for(ri i = 2; i <= N + 1; i ++) {
            if(!nop[i]) pr[++ tot] = i;
            for(ri j = 1; j <= tot; j ++) {
                int nx = i * pr[j]; if(nx > N + 1) break;
                nop[nx] = 1; if(i % pr[j] == 0) break;
            }
        }
        nop[2] = 1;
    }
    
    inline int dfs(int o) {
        for(int i = 1; i <= no; i ++)
        if(ex[o][i] && vis[i] != tim) {
            vis[i] = tim;
            if(!mat[i] || dfs(mat[i])) 
            return mat[i] = o, 1;
        }
        return 0;
    }
    
    int main() {
        Init();
        cin >> n;
        for(ri i = 1; i <= n; i ++) { int x; cin >> x; e[x] = 1; }
        
        for(ri i = 1; i <= N + 1; i ++)
        if(e[i] != e[i - 1]) {
            if(i & 1) js[++ nj] = i;
            else os[++ no] = i;
        }
    
        for(ri i = 1; i <= nj; i ++)
        for(ri j = 1; j <= no; j ++)
        if(!nop[abs(js[i] - os[j])]) ex[i][j] = 1;
    
        int num = 0, ans = 0;
    
        for(ri i = 1; i <= nj; i ++)
        ++ tim, num += dfs(i);
    
        nj -= num; no -= num;
        ans = num + nj / 2 * 2 + no / 2 * 2 + (nj & 1) * 3;
        printf("%d
    ", ans);
        return 0;
    }
  • 相关阅读:
    搭建非域AlwaysOn win2016+SQL2016
    从0开始搭建SQL Server AlwaysOn 第四篇(配置异地机房节点)
    从0开始搭建SQL Server AlwaysOn 第二篇(配置故障转移集群)
    从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn)
    从0开始搭建SQL Server AlwaysOn 第一篇(配置域控)
    四、基于Windows 2012配置SQL Server 2014 AlwaysOn
    三、安装SQLserver 2014(For AlwaysOn)
    二、 Windows 2012配置故障转移(For SQLServer 2014 AlwaysOn)
    Mybatis-SQL语句构建器类及日志
    Mybatis-JavaAPI
  • 原文地址:https://www.cnblogs.com/reverymoon/p/9709737.html
Copyright © 2011-2022 走看看