zoukankan      html  css  js  c++  java
  • Codeforces Round #663

    Codeforces Round #663

    http://codeforces.com/contest/1391

    C

    题意

    对于一个排列({p_1, p_2, dots, p_n}),对于每个数字(p_i),向前找第一个大于(p_i)(p_j)(i)(j)连一条边,向后同理。求多少种排列生成的图是有环的

    Solution

    • 对于(p_i),如果存在(p_j>p_i(j<i)), (p_k>p_i(k>i)),那么就是存在环的
    • 那么对于(forall i)都不成立时,就没有环
    • 此时就是序列的特点就是,数字(n)左边和右边向两边递减
    • 因此排列数就是(n!-2^{n-1})
    #include <cstdio>
    #include <stack>
    #include <set>
    #include <cmath>
    #include <map>
    #include <time.h>
    #include <vector>
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #include <queue>
    #include <iomanip>
    #include <cassert>
    #define P pair<int, int>
    #define LL long long
    #define LD long double
    #define PLL pair<LL, LL>
    #define mset(a, b) memset(a, b, sizeof(a))
    #define rep(i, a, b) for (int i = a; i < b; i++)
    #define PI acos(-1.0)
    #define random(x) rand() % x
    #define debug(x) cout << #x << " " << x << "
    "
    using namespace std;
    const LL inf = 0x3f3f3f3f3f3f3f3f;
    #ifdef DEBUG
    const int MAX = 2e3 + 50;
    #else
    const int MAX = 2e6  + 50;
    #endif
    const int mod = 1e9+7;
    void file_read(){
    #ifdef DEBUG
        freopen("in", "r", stdin);
    #endif
    }
    int main(){
        file_read();
        LL n;
        scanf("%lld
    ", &n);
        LL fact = 1;
        for(LL i = 1; i <= n; i++) {
            fact = fact * i % mod;
        }
        LL pow2 = 1;
        for(int i = 1; i < n; i++) {
            pow2 = pow2 * 2 % mod;
        }
        LL res = (fact - pow2) % mod;
        if(res < 0) res += mod;
        printf("%lld
    ", res);
    }
    

    D

    题意

    给一个01矩阵,对于每个变成位偶数的正方形,1的个数必须时奇数个,求最小改变01的次数

    Solution

    • 首先,对于4*4的矩阵是无解的,因此,(n,m)必有一个小于4,不妨假设(n<4), 且(n<m)
    • 然后问题就可以dp,枚举状态转移

    [ dp[i][mask_y] = min(dp[i-1][mask_x]+cost(i,mask_y), dp[i][mask_y]) ]

    #include <cstdio>
    #include <stack>
    #include <set>
    #include <cmath>
    #include <map>
    #include <time.h>
    #include <vector>
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <algorithm>
    //#include <memory.h>
    #include <cstdlib>
    #include <queue>
    #include <iomanip>
    #include <cassert>
    // #include <unordered_map>
    #define P pair<int, int>
    #define LL long long
    #define LD long double
    #define PLL pair<LL, LL>
    #define mset(a, b) memset(a, b, sizeof(a))
    #define rep(i, a, b) for (int i = a; i < b; i++)
    #define PI acos(-1.0)
    #define random(x) rand() % x
    #define debug(x) cout << #x << " " << x << "
    "
    using namespace std;
    const int inf = 0x3f3f3f3f;
    const LL __64inf = 0x3f3f3f3f3f3f3f3f;
    #ifdef DEBUG
    const int MAX = 2e3 + 50;
    #else
    const int MAX = 2e6  + 50;
    #endif
    const int mod = 1e9+7;
    void file_read(){
    #ifdef DEBUG
        freopen("in", "r", stdin);
    #endif
    }
    
    char s[10][MAX];
    int dp[MAX][10];
    int n, m;
    int cost(int col, int mask){
        int res = 0;
        for(int i = 1; i <= n; i++) {
            int x = s[i][col] - '0';
            int y = mask & 1;
            res += x != y;
            mask >>= 1;
        }
        return res;
    }
    bool check(int x, int y) {
        int A[2][10];
        for(int i = 1; i <= n; i++) {
            int a = x & 1;
            int b = y & 1;
            A[0][i] = a;
            A[1][i] = b;
            x >>= 1;
            y >>= 1;
        }
        int res = A[0][1] ^ A[0][2] ^ A[1][1] ^ A[1][2];
        if(!res) return false;
        if(n == 2) return true;
        res = A[0][2] ^ A[0][3] ^ A[1][2] ^ A[1][3];
        return res;
    }
    int main(){
        file_read();
        scanf("%d%d", &n, &m);
        if(n == 1 || m == 1) {
            puts("0");
            return 0;
        }
        if(n >= 4 and m >= 4) {
            puts("-1");
            return 0;
        }
        if(n <= m) {
            for(int i = 1; i <= n; i++) scanf("%s", s[i]+1);
        }
        else {
            for(int i = 1; i <= n; i++) {
                char t[10];
                scanf("%s", t+1);
                for(int j = 1; j <= m; j++) {
                    s[j][i] = t[j];
                }
            }
            swap(n, m);
        }
        // n <= m;
        mset(dp, 0x3f);
        int up = n == 2 ? 4 : 8;
        for(int i = 0; i < up; i++) {
            for(int j = 0; j < up; j++) {
                if(check(i, j))
                    dp[2][j] = min(dp[2][j], cost(1, i)+cost(2, j));
            }
        }
        for(int i = 3; i <= m; i++) {
            for(int x = 0; x < up; x++) {
                for(int y = 0; y < up; y++) {
                    if(check(x, y))
                        dp[i][y] = min(dp[i][y], dp[i-1][x]+cost(i, y));
                }
            }
        }
        int res = inf;
        for(int i = 0; i < up; i++ ) {
            res = min(res, dp[m][i]);
        }
        printf("%d
    ", res);
    }
    

    E

    题意

    给一个无向图连通图,有(n)个点,求下面任意一个,

    • 长度不小于(lceil n ceil)
    • 一个不小于(lceil n ceil)的点集,两两组成pair,pair之间的生成图边数不大于2

    Solution

    • 这是个构造题
    • 考虑在图上跑dfs后得到的树
    • 对于一个节点,除了树边,不会存在向旁边连的边,只有连向祖先的边
    • 如果存在一个深度不小于(lceil n ceil),答案就存在了
    • 否则,对于每个深度两两pair,对于任意的pair的生成图都是满足要求的。对于每一层,最多只剩一个,而且最多有(lfloor n floor),因此点集的大小不小于(n-lfloor n floor)
    #include <cstdio>
    #include <stack>
    #include <set>
    #include <cmath>
    #include <map>
    #include <time.h>
    #include <vector>
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <algorithm>
    //#include <memory.h>
    #include <cstdlib>
    #include <queue>
    #include <iomanip>
    #include <cassert>
    // #include <unordered_map>
    #define P pair<int, int>
    #define LL long long
    #define LD long double
    #define PLL pair<LL, LL>
    #define mset(a, b) memset(a, b, sizeof(a))
    #define rep(i, a, b) for (int i = a; i < b; i++)
    #define PI acos(-1.0)
    #define random(x) rand() % x
    #define debug(x) cout << #x << " " << x << "
    "
    using namespace std;
    const int inf = 0x3f3f3f3f;
    const LL __64inf = 0x3f3f3f3f3f3f3f3f;
    #ifdef DEBUG
    const int MAX = 2e3 + 50;
    #else
    const int MAX = 2e6  + 50;
    #endif
    const int mod = 1e9+7;
    void file_read(){
    #ifdef DEBUG
        freopen("in", "r", stdin);
    #endif
    }
    
    vector<int> G[MAX];
    bool vis[MAX];
    int dep[MAX];
    vector<int> dep_set[MAX];
    int p[MAX];
    int pr[MAX];
    void dfs(int u, int parent, int d) {
        dep[u] = d;
        vis[u] = 1;
        p[u] = parent;
        for(auto v : G[u]) {
            if(vis[v]) continue;
            dfs(v, u, d+1);
        }
    }
    int main(){
        file_read();
        int T;
        scanf("%d", &T);
        while (T--)
        {
            int n, m;
            scanf("%d%d", &n, &m);
            memset(vis, 0, sizeof(bool) * (n +50));
            memset(dep, 0, sizeof(int) * (n+50));
            memset(p, 0, sizeof(int) * (n+50));
            for(int i = 1; i <= n; i++) G[i].clear();
            for(int i = 1; i <= n; i++) dep_set[i].clear();
            for(int i = 1; i <= m; i++) {
                int u, v;
                scanf("%d%d", &u, &v);
                G[u].push_back(v);
                G[v].push_back(u);
            }
            dfs(1, -1, 1);
            int Max = -1, id = -1;
            for(int i = 1; i <= n; i++) {
                if(dep[i] > Max)  {
                    Max = dep[i];
                    id = i;
                }
            }
            if(Max * 2 >= n) {
                puts("PATH");
                vector<int> ans;
                int u = id;
                while(u != -1) {
                    ans.push_back(u);
                    u = p[u];
                }
                printf("%d
    ", ans.size());
                for(auto x: ans) printf("%d ", x);
                puts("");
                continue;
            }
            for(int i = 1; i <= n; i++) {
                dep_set[dep[i]].push_back(i);
            }
            puts("PAIRING");
            vector<P> ans;
            for(int k = 1; k <= Max; k++) {
                for(int i = 0; i+1 < dep_set[k].size(); i+=2) {
                    ans.emplace_back(dep_set[k][i], dep_set[k][i+1]);
                }
            }
            printf("%d
    ", ans.size());
            for(auto p : ans ) printf("%d %d
    ", p.first, p.second);
        }
        return  0;
    }
    

    A B

    A
    B

  • 相关阅读:
    编译 netcat for lineage-17.1-20210303-UNOFFICIAL-dipper.zip (ARM)
    Mi8-Android-arm 中网络接口命名:wlan0 & rmnet_data 《========》 VB-Android-x86 中网络接口命名:eth1 & wifi_eth
    HOW TO CHANGE LINUX KERNEL DMESG BUFFER SIZE
    Calculation of RTO in tcp and related open source implementation (Linux kernel, unbound) --- rtt, rttvar, cwnd, ssthresh
    图解Linux网络包接收过程
    Tcpprobe 在网络中的使用 --- tcp_probe has been removed from the kernel. --- Using ip-tcp_metrics --- Using ss (socket statistics)
    全面的 iPerf3 Android平台移植编译、运行过程记录
    socket、sock、sk_buff、net_device 关系图
    tcp: Add TCP_FREEZE socket option
    ECNU 2031 绝对值排序
  • 原文地址:https://www.cnblogs.com/sidolarry/p/13520605.html
Copyright © 2011-2022 走看看