• nowcoder 2020 多校 第三场


    nowcoder 2020 多校 第三场

    E Two Matchings

    题意

    可以简化题意为,每个点有个权重(w),两个点(i,j)相连的代价(abs(w_i-w_j)),找两个没有重叠的匹配使得代价最小

    Solution

    其实就是在将数字用长度为偶数的环连起来,求最小代价。进一步可以发现,环用长度为4或6,长度更长的环可以被分解达到更小的代价

    LL n;
    LL a[MAX];
    LL dp[MAX][2];
    LL four(const vector<LL> &a){
        return 2LL * (a[3]-a[0]);
    }
     
    LL six(const vector<LL> &a){
        return 2LL * (a[5]-a[0]);
    }
    int main(){
    #ifdef DEBUG
        freopen("in", "r", stdin);
    #endif
        int T;
        scanf("%d", &T);
        while (T--)
        {
            cin >> n;
            for(int i = 0; i < n; i++)
                cin >> a[i];
            sort(a, a+n);
            for(LL i = 0; i <= n; i++ )
                dp[i][0] = dp[i][1] = __64inf;
            dp[3][0] = 2LL * (a[3]-a[0]);
            dp[5][0] = 2LL * (a[5]-a[0]);
            dp[7][0] = 2LL * (a[7]-a[4] + a[3] - a[0]);
            for(LL i = 9; i < n; i+=2){
                dp[i][0] = min(dp[i-4][0], dp[i-4][1]) + four(vector<LL>({a[i-3], a[i-2], a[i-1], a[i]}));
                dp[i][1] = min(dp[i-6][0], dp[i-6][1]) +
                    six(vector<LL>({a[i-5], a[i-4], a[i-3], a[i-2], a[i-1], a[i]}));
            }
            printf("%d
    ", min(dp[n-1][0], dp[n-1][1]));
        }
         
    }
    

    F Fraction Construction Problem

    题意

    问有没有满足(displaystylefrac{c}{d}-frac{e}{f}=frac{a}{b})(c,d,e,f)

    Solution

    感觉是分类讨论,然后构造解

    void ex_gcd(LL a, LL b, LL &x, LL &y){
        if(b == 0){
            x = 1;
            y = 0;
            return;
        }
        ex_gcd(b, a % b, x, y);
        LL tmp = x;
        x = y;
        y = tmp - (a / b) * y;
    }
     
    LL p[MAX];
    LL cnt[MAX];
    vector<LL> prime;
    bool isprime[MAX];
    void init(){
        mset(isprime, 1);
        isprime[0] = isprime[1] = 0;
        for(int i = 2; i < MAX; i++){
            if(isprime[i]) {
                prime.push_back(i);
                cnt[i] = 1;
                p[i] = i;
            }
            for(int j = 0; j < prime.size() and i * prime[j] < MAX; j++){
                isprime[i * prime[j]] = 0;
                cnt[i * prime[j]] = i % prime[j] == 0 ? cnt[i] : cnt[i] + 1;
                p[i * prime[j]] = prime[j];
            }
        }
    }
     
    int main(){
    #ifdef DEBUG
    #else
        ios::sync_with_stdio(0);
        cin.tie(0);
    #endif
        init();
        int T;
        cin >> T;
        while (T--)
        {
            LL a, b;
            cin >> a >> b;
            LL g = __gcd(a, b);
            if(g > 1){
                LL bb = b / g, aa = a / g;
                cout << aa + 1 << " " << bb << ' ' << 1 << ' ' << bb << '
    ';
                continue;
            }
            LL tmp = b;
            if(cnt[b] <= 1) {
                cout << "-1 -1 -1 -1
    ";
                continue;
            }
            LL d = 1;
             tmp = b;
            while(tmp % p[b] == 0) {
                tmp /= p[b];
                d *= p[b];
            }
            LL f = b / d;
            LL c, e;
            ex_gcd(f, d, c, e);
            if(c < 0) {
                LL t = - (c -d + 1) / d;
                c += t * d;
                e -= t * f;
            }
            e = -e;
            e *= a;
            c *= a;
            cout << c << ' ' << d << ' ' << e << ' ' << f << '
    ';
        }
    }
    

    G Operating on a Graph

    题意

    给一个图,一开始每个点(i),属于(i)类,每次操作会吧某个类(x)的相邻的类归为(x),求最后每个点属于那个类

    Solution

    并查集模拟

    list<int> lk[MAX];
    vector<int> G[MAX];
    int fa[MAX];
    int Find(int x) {
        return fa[x] == x ? x : fa[x] = Find(fa[x]);
    }
    int main(){
    #ifdef DEBUG
        freopen64("in", "r", stdin);
    #endif
        int T;
        scanf("%d", &T);
        while (T--)
        {
            int n, m;
            scanf("%d%d",&n, &m);
            for(int i = 1; i <= n; i++){
                G[i].clear();
                fa[i] = i;
                lk[i].clear();
                lk[i].push_back(i);
            }
            for(int i = 0; i < m; i++) {
                int u, v;
                scanf("%d%d", &u, &v);
                u++, v++;
                G[u].push_back(v);
                G[v].push_back(u);
            }
            int q;
            scanf("%d",&q);
            while (q--)
            {
                int o;
                scanf("%d", &o);
                o++;
                int siz = lk[o].size();
                if(Find(o) != o) continue;
                for(int i = 0; i < siz; i++) {
                    int cur = lk[o].front();
                    lk[o].pop_front();
                    for(int j = 0; j < G[cur].size(); j++) {
                        int v = G[cur][j];
                        int pv = Find(v);
                        if(pv != o) {
                            fa[pv] = o;
                            lk[o].splice(lk[o].end(), lk[pv]);
                        }
                    }
                }
            }
            for(int i = 1; i <= n; i++)
                printf("%d ", Find(i)-1);
            puts("");
        }
        return 0;
    }
    
  • 相关阅读:
    mysql:添加索引
    mysql: update字段中带select
    ASP.NET Web API 2 入门
    notify()、notifyAll()和wait()
    Mybatis3 框架理解
    项目中用到的Java注解
    使用webservice实现App与服务器端数据交互
    IntelliJ idea 14 集成 tomcat 7
    使用adb签名并安装Android程序
    写了一个月的单元测试,总算明白大学里这门课白学了
  • 原文地址:https://www.cnblogs.com/sidolarry/p/13476261.html
Copyright © 2020-2023  润新知