• 2020-07-03 牛客编程挑战


    昨天多校训练在牛客组队,看到有个一战到底编程挑战,有些好奇就进去看看,做出来俩,都是模拟,第三个是动态规划,看了看没思路就走了,4号早晨起来补了一下。

    (有几个latex公式我暂时不太会搞,写出来可能看着有点蠢,见谅)

    1.简单题(重要极限+快速幂)

     解:题目中的O就是常见的重要极限$lim_{x o infty}(1+frac{1}{x})^x = e$,e的值是从math.h直接拿过来的,精度挺可以的,拿来直接快速幂就好了,后面保留小数那里我写的有点蠢,用cout的格式化输出会更好一些。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    double Pow(double x,int y){
        double res=1;
        while(y){
            if(y&1)res=res*x;
            x=x*x;
            y>>=1;
        }
        return res;
    }
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            double ans=(double)y*Pow(M_E,x);
            if(z==1)printf("%.1f
    ",ans);
            if(z==2)printf("%.2f
    ",ans);
            if(z==3)printf("%.3f
    ",ans);
            if(z==4)printf("%.4f
    ",ans);
            if(z==5)printf("%.5f
    ",ans);
        }
        return 0;
    }

    2.消息列表(模拟)

     解:这个题也没什么难度,我思路就是拿一个结构体存储每个人的信息(这个人的编号,消息总条数,是否置顶,最后一次发消息的时间),这样再用一个map,把所有人标记到,避免重复加入结构体。这样的话,最后只要将结构体排序就可以了,但是被卡住了空间,只能用vector,或者用牛客的自测调试多试几次,卡着空间限制应该也能过,不然的话vector也没法过是吧。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<map>
    #include<vector>
    #include<algorithm>
    #define maxn 1000001
    #define INF 1000000
    using namespace std;
    struct node{
        string s;
        int last;
        int tot;
    };
    vector<node>q;
    map<string,int>p;
    int T,n,cnt;
    char s1[10];
    string s2;
    bool cmp(node u,node v){
        if(u.last!=v.last)return u.last>v.last;
    }
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            cnt=0;
            vector<node>().swap(q);
            p.clear();
            for(int i=1;i<=n;i++){
                scanf("%s",s1);
                cin>>s2;
                if(!p[s2]){
                    node a;
                    cnt++;
                    p[s2]=cnt;
                    a.s=s2;
                    a.last=0;
                    a.tot=0;
                    q.push_back(a);
                }
                int now=p[s2]-1;
                if(s1[0]=='r'){
                    if(q[now].last>=INF)q[now].last=i+INF;
                    else q[now].last=i;
                    q[now].tot++;
                }
                else if(s1[0]=='v'){
                    q[now].tot=0;
                }
                else if(s1[0]=='u'){
                    if(q[now].last<INF)q[now].last+=INF;
                }
                else if(s1[1]=='o'){
                    if(q[now].last>=INF)q[now].last-=INF;
                }
                else if(s1[1]=='e'){
                    q[now].tot=0;
                    q[now].last=0;
                }
            }
            sort(q.begin(),q.end(),cmp);
    //        cout<<cnt<<endl;
            for(int i=0;i<cnt;i++){
                if(q[i].last==0)break;
                cout<<q[i].s<<" ";
                printf("%d
    ",q[i].tot);
            }
            puts("");
        }
        return 0;
    }

    3.陨石的秘密(动态规划)

     解:一道动态规划的题目。对于这些变量,设f[i][j][k][d]表示串中有i个()、j个[]、k个{}、深度不大于d时的方案总数。由定义可知,两个SS串拼在一起也是一个SS串,我们可以借此来进行动态规划。但是,若一个SS串为ABC,在计算时就会将AB+C和A+BC作为两个方案计算在内,但实际上是同一种方案。因此,为了避免重复,可以在动态规划时令一个串强制在最外面加上一个括号(满足要求的最小括号)。所以,首先枚举一个串中有的每种括号的数量,然后把所有括号分成两部分,对答案的贡献即为分成的两个串的乘积。注意取模。

    #include<iostream>
    #include<cstdio>
    #define mod 11380
    using namespace std;
    int n,l1,l2,l3,D,f[11][11][11][31];
    int main(){
        scanf("%d%d%d%d",&l1,&l2,&l3,&D);
        f[0][0][0][0]=1;
        for(int i=0;i<=l1;i++){
            for(int j=0;j<=l2;j++){
                for(int k=0;k<=l3;k++){
                    for(int l=1;l<=D;l++){
                        if(i!=0||j!=0||k!=0){
                            int tmp=0;
                            for(int a=0;a<k;a++){
                                tmp=(tmp+f[i][j][k-a-1][l]*f[0][0][a][l-1])%mod;
                            }
                            for(int b=0;b<j;b++){
                                for(int a=0;a<=k;a++)
                                tmp=(tmp+f[i][j-b-1][k-a][l]*f[0][b][a][l-1])%mod;
                            }
                            for(int c=0;c<i;c++){
                                for(int b=0;b<=j;b++){
                                    for(int a=0;a<=k;a++){
                                        tmp=(tmp+f[i-c-1][j-b][k-a][l]*f[c][b][a][l-1])%mod;
                                    }
                                }
                            }
                            f[i][j][k][l]=tmp;
                        }
                        else f[i][j][k][l]=1;
                    }
                }
            }
        }
        int ans=((f[l1][l2][l3][D]-f[l1][l2][l3][D-1])%mod+mod)%mod;
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    C#一些定义
    顺序
    针对IE8的css hack
    js 数字,金额 用逗号 隔开。数字格式化
    Ubuntu下使用Vi是方向键变乱码 退格键不能使用的解决方法
    UBUNTU中如何获得root权限
    区分IE8 、IE9 的专属css hack
    ubuntu 安装 Sublime Text 2
    PHP执行zip与rar解压缩方法
    使用ThinkPHP时,双引号导致插入数据库经过转义的处理
  • 原文地址:https://www.cnblogs.com/thmyl/p/13233908.html
Copyright © 2020-2023  润新知