zoukankan      html  css  js  c++  java
  • The Preliminary Contest for ICPC Asia Shenyang 2019

    The Preliminary Contest for ICPC Asia Shenyang 2019

    Texas hold'em Poker

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int maxn=1e6+10;
    int num[1000];
    int shun(){
        for (int i=15;i>=5;i--){
            if (num[i]&&num[i-1]&&num[i-2]&&num[i-3]&&num[i-4]) return i;
        }
        return -1;
    }
    struct node {
        int rk, num1, num2, num3;
        string na;
    
        bool operator<(const node a) const {
            if (rk != a.rk) return rk > a.rk;
            if (num1 != a.num1) return num1 > a.num1;
            if (num2 != a.num2) return num2 > a.num2;
            if (num3 != a.num3) return num3 > a.num3;
            return na < a.na;
        }
    }b[maxn];
    
    int n;
    string na,s;
    unordered_map<string,int>ma;
    
    int main() {
        //freopen("1.txt", "r", stdin);
        ma["A"] = 1;
        ma["2"] = 2;
        ma["3"] = 3;
        ma["4"] = 4;
        ma["5"] = 5;
        ma["6"] = 6;
        ma["7"] = 7;
        ma["8"] = 8;
        ma["9"] = 9;
        ma["10"] = 10;
        ma["J"] = 11;
        ma["Q"] = 12;
        ma["K"] = 13;
        while (cin >> n) {
            for (int i = 1; i <= n; i++) {
                cin >> na >> s;
                b[i].na = na;
                string ss;
                int len = s.length();
                for (int j = 0; j <= 15; j++) num[j] = 0;
                for (int j = 0; j < len; j++) {
                    ss = "";
                    if (s[j] != '1') ss = s[j];
                    else {
                        ss = s[j];
                        ss = ss + s[j + 1];
                        j++;
                    }
                    num[ma[ss]]++;
                }
                if (num[10] && num[11] && num[12] && num[13] && num[1]) {
                    b[i].rk = 8;
                    b[i].num1 = b[i].num2 = b[i].num3 = 0;
                    continue;
                }
                int k=shun();
                if (k!=-1) {
                    b[i].rk = 7;
                    b[i].num1 = k;
                    continue;
                }
    
                int f4 = 0, kk;
                for (int j = 0; j <= 15; j++) {
                    if (num[j] == 4) {
                        kk = j;
                        f4 = 1;
                        break;
                    }
                }
                if (f4) {
                    int kkk;
                    for (int j = 0; j <= 15; j++) {
                        if (num[j] == 1) {
                            kkk = j;
                            break;
                        }
                    }
                    b[i].rk = 6;
                    b[i].num1 = kk;
                    b[i].num2 = kkk;
                    b[i].num3 = 0;
                    continue;
                }
                int f3 = 0;
                for (int j = 0; j <= 15; j++) {
                    if (num[j] == 3) {
                        kk = j;
                        f3 = 1;
                        break;
                    }
                }
                if (f3) {
                    int kkk, f2 = 0;
                    for (int j = 0; j <= 15; j++) {
                        if (num[j] == 2) {
                            kkk = j;
                            f2 = 1;
                            break;
                        }
                    }
                    if (f2) {
                        b[i].rk = 5;
                        b[i].num1 = kk;
                        b[i].num2 = kkk;
                        b[i].num3 = 0;
                        continue;
                    }
                    int sum = 0;
                    for (int j = 0; j <= 15; j++) {
                        if (num[j] == 1) {
                            sum += j;
                        }
                    }
                    b[i].rk = 4;
                    b[i].num1 = kk;
                    b[i].num2 = sum;
                    b[i].num3 = 0;
                    continue;
                }
                kk = 0;
                for (int j = 0; j <= 15; j++) {
                    if (num[j] == 2) {
                        kk++;
                    }
                }
                if (kk == 2) {
                    int mx = 0, mi = 10000, kkk;
                    for (int j = 0; j <= 15; j++) {
                        if (num[j] == 2) {
                            mx = max(mx, j);
                            mi = min(mi, j);
                        }
                        if (num[j] == 1) {
                            kkk = j;
                        }
                    }
                    b[i].rk = 3;
                    b[i].num1 = mx;
                    b[i].num2 = mi;
                    b[i].num3 = kkk;
                    continue;
                }
                if (kk == 1) {
                    int kkk, sum = 0;
                    for (int j = 0; j <= 15; j++) {
                        if (num[j] == 2) {
                            kkk = j;
                        } else if (num[j]) sum += j;
                    }
                    b[i].rk = 2;
                    b[i].num1 = kkk;
                    b[i].num2 = sum;
                    b[i].num3 = 0;
                    continue;
                }
                int sum = 0;
                for (int j = 0; j <= 15; j++) {
                    if (num[j]) sum += j;
                }
                b[i].rk = 1;
                b[i].num1 = sum;
                b[i].num2 = 0;
                b[i].num3 = 0;
            }
            sort(b + 1, b + n + 1);
            for (int i = 1; i <= n; i++) {
                cout << b[i].na << endl;
            }
        }
        return 0;
    }
    

    Fish eating fruit

    题意:求一颗树中所有点对(a,b)的路径长度,路径长度按照模3之后的值进行分类,最后分别求每一类的和

    分析:树形DP

    dp[i][j]表示以 i 为根的子树中,所有子节点到 i 的路径长度模3等于 j 的路径之和

    c[i][j]表示以 i 为根的子树中,所有子节点到 i 的路径长度模3等于 j 的点数

    ok[i][j]表示以 i 为根的子树中,是否有子节点到 i 的路径长度模3等于 j

    每次只考虑所有经过根 x 的路径,并且路径的一个端点在 x 的一颗子树上,另一个端点在 x 的另一颗子树上。(可以想到其他所有情况都可以在考虑 x 的子树结点或者是x的祖先结点时被考虑到)
    假设当前枚举到 x 的子节点 y,之前遍历的子节点已经使得三个数组更新。那么我们假设要计算的路径的起点在 y ,要计算的路径的终点在之前遍历过的子节点中。

    计算答案贡献:
    关于x-y的连边的贡献为

    c[x][a]*c[y][b]*edge

    关于起点到 y 的所有路径长度的贡献为

    c[x][a]*dp[y][b]

    关于x到终点的所有路径长度的贡献为

    c[y][b]*dp[x][a]

    最终边权所属分类为(a+b+edge)%3累加到答案即可

    关于更新 x

    用 y 来更新 x

    dp[x][(a+edge)%3]+=dp[y][a]+edgec[y][a]

    ok[x][(a+edge)%3]=true

    c[x][(a+edge)%3]+=c[y][a]

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    
    const int maxn=10020;
    const int maxm=200010;
    const ll mod=1e9+7;
    
    int t,head[maxn];
    struct edge{
        int v,next;
        ll w;
    }e[maxm];
    bool ok[maxn][3];
    int n;
    ll dp[maxn][3],c[maxn][3],ans[3];
    
    void add(int u,int v,int w) {
        t++;
        e[t].v = v;
        e[t].w = w;
        e[t].next = head[u];
        head[u] = t;
    }
    
    void dfs(int u,int fa) {
        for (int i = head[u]; i; i = e[i].next) {
            int v = e[i].v;
            if (v == fa) continue;
            dfs(v, u);
            ll w = e[i].w;
            for (int j = 0; j < 3; j++) {
                for (int k = 0; k < 3; k++) {
                    if (ok[u][j] && ok[v][k]) {
                        ans[(j + k + w) % 3] += (dp[u][j] * c[v][k] % mod + dp[v][k] * c[u][j] % mod) % mod;
                        ans[(j + k + w) % 3] += w * c[u][j] % mod * c[v][k] % mod;
                        ans[(j + k + w) % 3] %= mod;
                    }
                }
            }
            for (int j = 0; j < 3; j++) {
                if (ok[v][j]) {
                    dp[u][(j + w) % 3] += dp[v][j] + w * c[v][j] % mod;
                    dp[u][(j + w) % 3] %= mod;
                    c[u][(j + w) % 3] += c[v][j];
                    ok[u][(j + w) % 3] = 1;
                }
            }
        }
    }
    
    int main() {
        while (~scanf("%d", &n)) {
            t=0;
            for (int i = 1; i <= n; i++) {
                dp[i][0] = dp[i][1] = dp[i][2] = 0;
                c[i][1] = c[i][2] = 0;
                c[i][0] = 1;
                ok[i][0] = 1;
                ok[i][1] = ok[i][2] = 0;
                head[i] = 0;
                ans[0]=ans[1]=ans[2]=0;
            }
            for (int i = 1, u, v,w; i < n; i++) {
                scanf("%d%d%d", &u, &v, &w);
                u++;
                v++;
                add(u, v, w);
                add(v, u, w);
            }
            dfs(1, 0);
            printf("%lld %lld %lld
    ", ans[0] * 2 % mod, ans[1] * 2 % mod, ans[2] * 2 % mod);
        }
        return 0;
    }
    

      

  • 相关阅读:
    Jedis、RedisTemplate、StringRedisTemplate之间的比较
    阿里云服务器搭建DiscuzQ
    阿里云Docker加速镜像配置
    IDEA不卡配置
    Tomcat中出现"RFC 7230 and RFC 3986"错误的解决方法
    Eclipse设置保存时自动格式化代码
    VUE中v-for和v-if不能同时使用的问题
    JS中设置cookie,读取cookie,删除cookie
    JS中数组的拷贝方法
    在VSCode中开启ESLint风格审查
  • 原文地址:https://www.cnblogs.com/Accpted/p/11521281.html
Copyright © 2011-2022 走看看