• Codeforces Round #223 (Div. 2)


    A. Sereja and Dima

    题意:两个人从序列两端取大的一个值,轮流取,问最后各自的和。

    分析:直接模拟。

    /****************************************
    * File Name: 223a.cpp
    * Author: sky0917
    * Created Time: 2014年01月12日 22:59:43
    ****************************************/
    #include <map>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 100005;
    
    int n, m;
    int a[1002];
    int b[2];
    int main(){ 
        while (scanf("%d",&n)!=EOF){
            int l = 0, r = n-1;
            for (int i=0; i<n; i++)
                scanf("%d",&a[i]);
            int tot = 0;
            b[0] = b[1] = 0;
            while (l <= r){
                tot++;
                if (a[l] > a[r]){
                    b[tot&1] += a[l];       
                    l++;
                }
                else {
                    b[tot&1] += a[r];
                    r--;
                }
            }
            printf("%d %d
    ",b[1],b[0]);
        }   
        return 0;
    }
    A

    B. Sereja and Stairs

    题意:一个人有m个数字,现在他要选出尽可能多的数字摆成一个序列,满足以下条件:

           a1 < a2 < ... < ai - 1 < ai > ai + 1 > ... > a|a| - 1 > a|a|.

    分析: 由于数字的值最大是5000,所以可以用标记数组记录每个数出现的次数,然后先从小到大遍历一遍输出,再从大到小遍历输出。

    /****************************************
    * File Name: 223b.cpp
    * Author: sky0917
    * Created Time: 2014年01月12日 23:29:26
    ****************************************/
    #include <map>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 100005;
    
    int n;
    int a[maxn];
    int b[5005];
    int res[maxn];
    int main(){
        while (scanf("%d",&n)!=EOF){
            memset(b, 0, sizeof(b));
            int va;
            for (int i=0; i<n; i++){
                scanf("%d",&va);
                b[va]++;    
            }
            int tp = 0;
            int ma = 0;
            for (int i=1; i<=5000; i++){
                if (b[i]){
                    ma = i;
                    b[i]--;
                    res[tp++] = i;  
                }
            }
            for (int i=ma-1; i>=1; i--){
                if (b[i]){
                    res[tp++] = i;
                }
            }
            printf("%d
    ",tp);
            for (int i=0; i<tp; i++){
                printf("%d%c",res[i],i==tp-1?'
    ':' ');
            }
        }
        return 0;
    }
    B

    C. Sereja and Prefixes

    题意:给出m < 100000 次操作,每次操作两种:

           1 xi   :表示在序列结尾加上一个值为 xi 的数

           2 li ci:  表示把序列的前li个数重复ci次放在序列结尾

          给出 n 个数 ai

          输出序列中第 ai 个数的值

          由于 li <= 100000 所以可以仅保留序列的前 100000 个数即可,

         对于 1 情况看看 len + 1 是否等于 ai,等于就输出,否则不管,

         对于情况 2 第 ai 个数的值为 (ai-len) % li 个位置的数,直接输出即可,每次 len += ci * li

    /****************************************
    * File Name: 223c.cpp
    * Author: sky0917
    * Created Time: 2014年01月13日  9:33:31
    ****************************************/
    #include <map>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 100005;
    int m, n;
    long long va[maxn];
    
    struct node{
        int ty;
        long long li, ci;
        long long ai;
    }q[maxn];
    
    long long a[maxn];
    void solve(){
        int tt = 0;
        int tp = 0;
        long long len = 0;
        for (int i=0; i<m; i++){
            if (q[i].ty == 1){
                len += 1;
                if (tt < n && len == va[tt]){
                    tt++;
                    printf("%I64d ",q[i].ai);
                }
                if (tp < 100000){
                    a[tp++] = q[i].ai;
                }
                    
            }    
            else{
               //printf("vatt= %I64d len= %I64d
    ",va[tt],len);
               while (tt < n && len + q[i].ci*q[i].li >= va[tt]){
                   long long xu = (va[tt]-len) % q[i].li;
                   xu = (xu-1 + q[i].li) % q[i].li;
                   printf("%I64d ", a[xu]);   
                   tt++;
               }
    
               len += q[i].ci * q[i].li;
    
               for (long long j=0; j<q[i].ci && tp<100000; j++){
                    for (long long k=0; k<q[i].li && tp<100000; k++){
                        a[tp++] = a[k];
                    }
               }
                
            }
        }    
    }
    
    int main(){
        while (scanf("%d",&m)!=EOF){
            for (int i=0; i<m; i++){
                scanf("%d",&q[i].ty);
                if (q[i].ty == 1){
                    scanf("%I64d",&q[i].ai);
                }
                else{
                    scanf("%I64d %I64d",&q[i].li,&q[i].ci);
                }
            }    
            scanf("%d",&n);
            for (int i=0; i<n; i++){
                scanf("%I64d",&va[i]);
            }
            solve();
        }        
        return 0;
    }
    C

    E. Sereja and Brackets

    题意:给出一个类似  ())(())(())( 的括号序列,长度 m < 1000000,给出 n 个询问 l, r,输出[l, r]区间内最多有多少个匹配的括号,n<100000。

    分析:树状数组+离线。

            先把询问保存,然后按照 ( 位置从大到小排序,

            从括号序列的尾部向前遍历,维护一个 ) 位置的栈

            如果遇到 i 位置为 ) 则把 i 入栈,

            如果遇到 i 位置为 ( ,如果栈不为空,则 add(pos = st[top]), 即把区间[1, st[top]] 都+1

            对于当前位置 i, 计算所有询问左区间 = i 的值为 getsum(r).

    /****************************************
    * File Name: 223e.cpp
    * Author: sky0917
    * Created Time: 2014年01月13日 10:15:04
    ****************************************/
    #include <map>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 1000005;
    const int maxm = 100005;
    
    char s[maxn];
    struct node{
        int l, r;
        int xu;
    }q[maxm];
    int n, m;
    
    bool cmp(node a, node b){
        return a.l > b.l;
    }
    
    int res[maxm];
    
    inline int lowbit(int x){
        return (x) & (-x);
    }
    int tr[maxn];
    void add(int pos){
        while (pos < m){
            tr[pos] += 1;
            pos += lowbit(pos);
        }
    }
    int getsum(int pos){
        int su = 0;
        while (pos > 0){
            su += tr[pos];
            pos -= lowbit(pos);
        }
        return su;
    }
    
    int st[maxn];
    int tp;
    void solve(){
        sort(q, q+n, cmp);
        tp = 0;
        int j = 0;
        for (int i=m-1; i >= 0; i--){
            if (s[i] == ')'){
                st[++tp] = i;
            }   
            else if (tp > 0){
                add(st[tp--]);  
            }
            while (j < n && q[j].l == i){
                res[q[j].xu] = getsum(q[j].r);      
                j++;
            }   
        }
        for (int i=0; i<n; i++){
            printf("%d
    ",res[i]*2);
        }
    }
    
    int main(){
        while (scanf("%s",s)!=EOF){
            m = strlen(s);
            scanf("%d", &n);
            for (int i=0; i<n; i++){
                scanf("%d %d",&q[i].l,&q[i].r);
                q[i].l--, q[i].r--;
                q[i].xu = i;
            }
            solve();    
        }   
        return 0;
    }
    E

         

  • 相关阅读:
    58.最后一个单词的长度
    四种不同的SNP calling算法call低碱基覆盖度测序数据时,SNVs数量的比较(Comparing a few SNP calling algorithms using low-coverage sequencing data)
    斯坦福大学公开课机器学习:advice for applying machine learning | model selection and training/validation/test sets(模型选择以及训练集、交叉验证集和测试集的概念)
    Methods for follow-up research of exome analysis:外显子后续分析研究思路总结
    斯坦福大学公开课机器学习: advice for applying machine learning
    斯坦福大学公开课机器学习:advice for applying machine learning
    斯坦福大学公开课机器学习: neural networks learning
    看了一场不正经的艺术展(以色列:飞鸟与曼陀罗)
    无心准备组会,唯画画能缓解焦虑
    蛋白质结构模型和功能预测:Swiss-model工具的使用
  • 原文地址:https://www.cnblogs.com/sky0917/p/3517029.html
Copyright © 2020-2023  润新知