zoukankan      html  css  js  c++  java
  • Codeforces Round #502 (in memory of Leopoldo Taravilse, Div. 1 + Div. 2)

    A - The Rank

    题意:定义排名为:先排总分,总分相同排id,求id为1的人的rnk。

    题解:implement

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    pair<int, int> p[1005];
    
    void test_case() {
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; ++i) {
            int sum = 0;
            for(int j = 1, x; j <= 4; ++j) {
                scanf("%d", &x);
                sum += x;
            }
            p[i] = {-sum, i};
        }
        sort(p + 1, p + 1 + n);
        for(int i = 1; i <= n; ++i) {
            if(p[i].second == 1) {
                printf("%d
    ", i);
                return;
            }
        }
    }
    
    int main() {
    #ifdef KisekiPurin
        freopen("KisekiPurin.in", "r", stdin);
    #endif // KisekiPurin
        int t = 1;
        for(int ti = 1; ti <= t; ++ti) {
            //printf("Case #%d: ", ti);
            test_case();
        }
    }
    

    B - The Bits

    题意:有两个01串a,b,求交换a串的一对01位之后使得a|b的值变化的数量。

    题解:分类讨论。显然同种字符换是没有意义的。假如某个ai=1且bi=1,那么需要把ai和某个aj=0且bj=0互换。假如某个ai=1且bi=0,那么需要把ai和某个aj=0互换。假如某个ai=0且bi=1,那么可以和aj=1且bj=0互换。假如某个ai=0且bi=0,那么可以和aj=1互换。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int a[100005], b[100005];
    int cnt[2][2];
    
    void test_case() {
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; ++i)
            scanf("%1d", &a[i]);
        for(int i = 1; i <= n; ++i) {
            scanf("%1d", &b[i]);
            ++cnt[a[i]][b[i]];
        }
        ll sum = 0;
        for(int i = 1; i <= n; ++i) {
            if(a[i] == 0 && b[i] == 0)
                sum += cnt[1][0] + cnt[1][1];
            else if(a[i] == 0 && b[i] == 1)
                sum += cnt[1][0];
            else if(a[i] == 1 && b[i] == 0)
                sum += cnt[0][0] + cnt[0][1];
            else
                sum += cnt[0][0];
        }
        printf("%lld
    ", sum / 2);
    }
    
    int main() {
    #ifdef KisekiPurin
        freopen("KisekiPurin.in", "r", stdin);
    #endif // KisekiPurin
        int t = 1;
        for(int ti = 1; ti <= t; ++ti) {
            //printf("Case #%d: ", ti);
            test_case();
        }
    }
    

    C - The Phone Number

    题意:给一个n,构造一个[1,n]排列,使得最长严格上升子序列长度+最长严格下降子序列长度最小。

    考虑样例的构造法,比如n=6:

    456123
    

    上升为3,下降为2。

    564312
    

    上升为2,下降为3。

    其中下界肯定是2,这个毫无疑问,那么3能不能变小?要使得上升最小,必须把二元组这样编排(除非搞个全部降序,上升就是1,下降就是n),这样做下降的长度就是n/2。

    大胆猜测是不是分成根号n组呢?

    789456123
    

    这样下降是3,上升也是3。看样子,把其中一个长度控制在x,就要分成n/x组,且组之间逆序排列。不会证明,先莽一发。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int ans[100005];
    
    void test_case() {
        int n;
        scanf("%d", &n);
        int L = sqrt(n);
        int R = L + 1;
        int cntR = n % L;
        int cntL = (n - R * cntR) / L;
        int top = 0, cur = n;
        for(int i = 1; i <= cntL; ++i) {
            int ccur = cur - L + 1;
            for(int j = 1; j <= L; ++j)
                ans[++top] = ccur++;
            cur -= L;
        }
        for(int i = 1; i <= cntR; ++i) {
            int ccur = cur - R + 1;
            for(int j = 1; j <= R; ++j)
                ans[++top] = ccur++;
            cur -= R;
        }
        for(int i = 1; i <= n; ++i)
            printf("%d%c", ans[i], " 
    "[i == n]);
    }
    
    int main() {
    #ifdef KisekiPurin
        freopen("KisekiPurin.in", "r", stdin);
    #endif // KisekiPurin
        int t = 1;
        for(int ti = 1; ti <= t; ++ti) {
            //printf("Case #%d: ", ti);
            test_case();
        }
    }
    

    关于这种LIS的性质好像不太熟练,都是看直觉?这个是 Dilworth's theorem (偏序集分解定理)但是不懂他在说什么。大概是一个结论:一个长mn+1的序列,存在长m+1的链,或者存在长n+1的反链。算了伤脑筋。组合数学学得不好。

    D - The Wu

    题意:有m个长度为n(<=12)的01串s,q个长度也是n的01串t,定义两个串的“相似度”为他们相等的位的权值之和,对于每个t求“相似度”不超过k的s的数量。

    题解:01串的相等位就是异或之后取反。预处理每种相等位的组合的“相似度”,然后暴力枚举st的组合(2^24),要套个快读01串,不能分为12次scanf("%1d")读入。快写就没什么显著提升。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
     
    //异或值为x的Wu值
    int dp1[1 << 12];
    //s串的数量
    int cnt[1 << 12];
    //t串拥有的不超过k的Wu的数量
    int dp2[1 << 12][101];
     
    int n;
     
    int ReadBinary() {
        int cur = 0;
        char tmp = getchar();
        while(tmp != '0' && tmp != '1')
            tmp = getchar();
        for(int i = 0; i < n; ++i) {
            cur = (cur << 1) | (tmp - '0');
            tmp = getchar();
        }
        return cur;
    }
     
    void test_case() {
        int  m, q;
        scanf("%d%d%d", &n, &m, &q);
        for(int i = 0; i < n; ++i)
            scanf("%d", &dp1[1 << (n - 1 - i)]);
        for(int i = 1; i < (1 << n); ++i) {
            if(dp1[i])
                ;
            else {
                int lowbiti = (i & -i);
                dp1[i] = dp1[i ^ lowbiti] + dp1[lowbiti];
            }
        }
        for(int i = 1; i <= m; ++i) {
            int cur = ReadBinary();
            ++cnt[cur];
        }
        int BITMASK = (1 << n) - 1;
        for(int i = 0; i < (1 << n); ++i) {
            for(int j = 0; j < (1 << n); ++j) {
                int k = dp1[BITMASK ^ (i ^ j)];
                if(k > 100)
                    continue;
                dp2[i][k] += cnt[j];
            }
            for(int k = 1; k <= 100; ++k)
                dp2[i][k] += dp2[i][k - 1];
        }
        for(int i = 1; i <= q; ++i) {
            int cur = ReadBinary();
            int k;
            scanf("%d", &k);
            printf("%d
    ", dp2[cur][k]);
        }
    }
     
    int main() {
    #ifdef KisekiPurin
        freopen("KisekiPurin.in", "r", stdin);
    #endif // KisekiPurin
        int t = 1;
        for(int ti = 1; ti <= t; ++ti) {
            //printf("Case #%d: ", ti);
            test_case();
        }
    }
    

    一种复杂度更低的方法是:对于每种串s,保存其高6位在t的低6位的不同取值下的贡献,然后对于t串,就可以遍历s的高6位然后直接取出来,复杂度缩减了2^6(对于每个t只需要枚举其一半了)。

  • 相关阅读:
    sqlhelper使用指南
    大三学长带我学习JAVA。作业1. 第1讲.Java.SE入门、JDK的下载与安装、第一个Java程序、Java程序的编译与执行 大三学长带我学习JAVA。作业1.
    pku1201 Intervals
    hdu 1364 king
    pku 3268 Silver Cow Party
    pku 3169 Layout
    hdu 2680 Choose the best route
    hdu 2983
    pku 1716 Integer Intervals
    pku 2387 Til the Cows Come Home
  • 原文地址:https://www.cnblogs.com/KisekiPurin2019/p/11908413.html
Copyright © 2011-2022 走看看