• 11.46.2020质检


    B.是一个DP

    有一群人非常喜欢ACM 比赛,只要是跟ACM 相关的东西他们都非常在意。有一天,他们在鲁东大学的校园里看到了一个仅由”A”、”C”、”M”这三个字符组成的横幅。一时兴起,他们想要知道这个横幅里出现了几次”ACM”,你也是其中的一员,请编写一个程序解决这个问题。

    Input

    输入只有一行,包含一个字符串ss(length(s)1e5 ),只含有A、C、M 这三种字母。

    Output

    在一行中输出给定的字符串中含有多少个ACM。最终的结果可能比较大,请对结果用1000000007 取余。

    Samples

    Input Copy
    CAACAM
    Output
    2

    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+100;
    const int mod=1000000007;
    int main(){
        ll a=0,c=0,m=0;
        string str;
        cin>>str;
        for(int i=0;i<str.size();i++){
            if(str[i]=='A'){
                a++;
            }
            else if(str[i]=='C'){
                c+=a;
            }
            else if(str[i]=='M'){
                m+=c;
            }
            a=a%mod;
            c=c%mod;
            m=m%mod; 
        } 
        cout<<m%mod<<endl;
    }
    View Code

    最近,一直在IT行业"搬砖"的程序员小张考虑到自己日渐稀疏的发量,决定跳槽去做工地"搬砖"做一名真正的民工,可是小张进入工地的第二天,包工头就交代给了小张另一个对发量极为不利的烧脑任务。现在有MM(1M20)块工地的石材,高度分别HiHi米(1Hi1000,000),这些石材的垒起来的总高度为SS,包工头让小张从这些石材中选出一些石材,垒出一个工作台,要求工作台的高度不能低于N 米(1N)1≤N),并且高出N米的长度越少越好,这样方便工人站在该工作台上作业。现在,你能帮小张从这M块石材中找出一个集合,垒起来的高度满足包工头的要求吗?如果不能满足条件,就输出能组成的最大高度。

    Input

    第一行MM 和NN 分别表示石材的个数和包工头要求的最低高度

    第二到M+1M+1 行,H1,H2,,HMH1,H2,…,HM 表示每块石材的高度

    Output

    输出一个整数,表示满足包工头要求的石材垒出的高度。

    Samples

    Input Copy
    5 16
    3
    1
    3
    5
    6
    Output
    17

    Source

    2020年烟大校赛

    一看数据范围1<=M<=20,第一反应就是二进制枚举
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+100;
    const int mod=1000000007;
    int a[maxn];
    int main(){
        int n,m;
        cin>>n>>m;
        ll p=0;
        for(int i=0;i<n;i++){
            cin>>a[i];
            p+=a[i]; 
        }
        if(p<=n){
            cout<<p<<endl;
            return 0;
        }
        int z=0x3f3f3f;
        int pp=0x3f3f3f;
        for(int i=0;i<(1<<n);i++){    
            ll sum=0;
            for(int j=0;j<n;j++){
                if(i&(1<<j)){
                    sum+=a[j];
                }    
            }
            if(sum>=m){
                if((sum-m)<=pp){
                    pp=sum-m;
                    z=sum;
                }
            } 
        }
        cout<<z<<endl;
    }

    最近,一直在IT 行业"搬砖"的程序员小张考虑到自己日渐稀疏的发量,决定跳槽去做工地"搬砖"做一名真正的民工,可是小张进入工地的第一天,包工头就交代给了小张一个对发量极为不利的烧脑任务。现在有MM(1M200001≤M≤20000)块工地的石材,高度分别HiHi米(1Hi10000),这些石材的垒起来的总高度为SS,包工头让小张从这些石材中选出一些石材,垒出一个工作台,要求工作台的高度不能低于NN 米(1NS1≤N≤S),且石材的数目尽可能少。现在,你能帮小张从这M 块石材中找出一个集合,垒起来的高度满足包工头的要求吗?

    Input

    输入包含两行:

    第一行MM 和NN 分别表示石材的个数和包工头要求的最低高度

    第二到M+1M+1 行,H1,H2,,HMH1,H2,…,HM 表示每块石材的高度

    Output

    输出一个整数,表示垒出不低于NN 米的最少石材数目。

    Samples

    Input Copy
    6 40
    6
    18
    11
    13
    19
    11
    Output
    3

    Source

    贪心:排序就行

    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+100;
    const int mod=1000000007;
    ll a[maxn];
    bool cmp(int a,int b){
        return a>b; 
    }
    int main(){
        ll m,n;
        cin>>m>>n;
        for(int i=1;i<=m;i++){
            cin>>a[i];
        }
        sort(a+1,a+m+1,cmp);
        int sum=0; 
        for(int i=1;i<=m;i++){
            sum+=a[i];
            if(sum>=n){
                cout<<i<<endl;
                return 0;
            }
        }
    }

    Description

    圣诞节快要到了,圣诞老爷爷要打包n 份糖果分给小朋友们,假设圣诞老爷爷已经打包好了m 份糖果了。恰好轮到小明了,小明因为是里面最小的小朋友,所以小明可以要两份,并且可以提出要求,小明希望能分到这n 份糖果中最多糖果的一份和最少糖果的一份,并且里面的糖果恰好为a 和b 个,这可难到圣诞老爷爷了,打包好的不可以拆开,剩下的nm 份都可以现装糖果,问能否满足小明的要求。

    Inpu

    输入包含两行:

    第一行输入n,m,a,b 其中a 和b 的大小关系不确定。

    第二行表示已经打包好的m 份糖果各自数量1n,m,a,b1000mn

    Output

    输出YES 或者NO

    Samples

    Input Copy
    3 2 1 2
    1 2
    Output
    YES

    Source

    2020年烟大校赛

    就是考虑的情况比较多(主要是枚举n-m)
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+100;
    const int mod=1000000007;
    int aa[maxn];
    int main(){
        int n,m,a,b;
        cin>>n>>m>>a>>b;
        if(a>b){
            swap(a,b);
        }
        int flag=1;
        for(int i=1;i<=m;i++){
            cin>>aa[i];
            if(aa[i]!=aa[1]){
                flag=0;//有不相同的 
            }
        } 
        if(a==b){ 
            if(flag==1&&n>=2){
                printf("YES
    ");
            }
            else{
                printf("NO
    ");
            }
            return 0;
        }
        sort(aa+1,aa+m+1);
        int mi=aa[1];
        int ma=aa[m];
        if(n<=1){
            printf("NO
    ");
            return 0;
        }
        else{
            if(n-m>=2){//当有大于2个的时候 
                if(mi<a||ma>b){//只要超过a  b就行 
                    printf("NO
    "); 
                }
                else{
                    printf("YES
    ");
                }
                return 0;
            }
            else if((n-m)==1){
                if(mi<a||ma>b){//超过a  b肯定是不行的 
                    printf("NO
    ");
                    return 0;
                }
                else if(mi==a||ma==b){//必须再超过a b的情况下,至少一个端点是a,b 
                    printf("YES
    ");
                    return 0;
                }
                else{
                    printf("NO
    ");
                    return 0;
                }
            }
            else if(n==m){//不能再加的话,那就是a==mi,b==ma 
                if(a==mi&&b==ma){
                    printf("YES
    "); 
                }            
                else{
                    printf("NO
    ");
                }
                return 0;
            }
        }
    }

    你喜欢套娃,根本停不下来。为了终止你的套娃行为,算法之神定义了两个函数g(如下图所示)使得你的套娃行为最终停止下来。

     

    为了惩罚你的套娃行为,算法之神交给了你一项任务:

    你需要进行QQ 次查询。在每一次查询中,你将被给予三个数字l,rl,r 和kk。你需要在区间[l,r][l,r]上找到满足公式g(x)=kg(x)=k 的xx 的数量(lxrl≤x≤r)。

    Input

    第一行给出整数QQ( 1Q21e5)表示有Q 次查询。

    接下来的QQ 行,每行包括三个整数l,rl,r 和kk(1lr1e6 ,1k9

    Output

    对于每一次查询,输出单独一行,表示本次查询的结果。

    Samples

    Input Copy
    4
    22 73 9
    45 64 6
    47 55 7
    2 62 4
    Output
    1
    4
    0
    8

    Hint

    对于第一次查询,在区间[22,73]上,只有33 这个数字满足g(33)=9

    因为g(33)=g(33)=g(9)=9

    本题输入量较大,建议使用scanf 函数

    Source

    2020年烟大校赛


    输出的时候肯定要o(1)输出
    所以要用前缀和的思想,处理出来
    ss[i][k]是指的是前i个数字为k的个数
    #pragma GCC optimize(1)
    #pragma GCC optimize(2)
    #pragma GCC optimize(3,"Ofast","inline")
    #include<cstring>
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    struct ios {
        inline char gc(){
            static const int IN_LEN=1<<18|1;
            static char buf[IN_LEN],*s,*t;
            return (s==t)&&(t=(s=buf)+fread(buf,1,IN_LEN,stdin)),s==t?-1:*s++;
        }
        template <typename _Tp> inline ios & operator >> (_Tp&x){
            static char ch,sgn; ch = gc(), sgn = 0;
            for(;!isdigit(ch);ch=gc()){if(ch==-1)return *this;sgn|=ch=='-';}
            for(x=0;isdigit(ch);ch=gc())x=x*10+(ch^'0');
            sgn&&(x=-x); return *this;
        }
    }io;
    const int maxn=1e6+1000;
    const int mod=1000000007;
    int a[maxn][11];
    int ss[maxn][11];
    int s[maxn];
    int p[maxn];
    void inint(){
        for(register int i=1;i<=9;i++){
            a[i][i]++;
            for(register int j=1;j<=9;j++){
                ss[i][j]=ss[i-1][j]+a[i][j];
            } 
            s[i]=i;
        }
        int p;
        int sum,z;
        for(register int i=10;i<=1e6;i++){
            p=i;
            sum=1;
            while(p){
                if(p%10!=0){
                    sum*=(p%10);
                }
                p/=10;
            }
            z=s[sum];
            a[i][z]++;
            for(register int j=1;j<=9;j++){
                ss[i][j]=ss[i-1][j]+a[i][j];
            } 
            s[i]=z;
        }
    }
    int main(){
        inint();
        int t;
        int l,r,k;
        scanf("%d",&t);
        while(t--){
            io>>l>>r>>k; 
            printf("%d
    ",ss[r][k]-ss[l-1][k]);
        } 
        return 0;
    } 


    一位拥有操作天气超能力的少女说道:“呐,现在开始就要放晴了哦~”

    于是倾盆大雨停止了,天空放晴了……

    她发现一些路边的石柱接住了一些雨水,她很好奇,这些石柱接住了多少雨水呢?如下图所示,这是nn 个石柱的侧视图,请计算按此排列的石柱接住了多少雨水(黑色为石柱,蓝色为雨水)。

    Input

    第一行,一个非负整数nn(0n3×1e4 ),表示有nn 个石柱。

    第二行,nn 个非负整数组成的序列,表示石柱的高度height[i]0height[i]1e50i<n)。

    Output

    输出只有一行,包含一个非负整数numnum 表示石柱可以接住的雨水量。

    Samples

    Input Copy
    12
    0 1 0 2 1 0 1 3 2 1 2 1
    Output
    6
    模拟了一下过程,我也承认它有点丑

    就是找一个最大值,这个最大值肯定是要有贡献的,两边枚举,
    #include<iostream>
    #include<algorithm>
    #define INF 2e9+10000
    using namespace std;
    const int maxn=5e6+100;
    int a[maxn];
    int main(){
        int n;
        cin>>n;
        int ma=0; 
        for(int i=1;i<=n;i++){
            cin>>a[i];
            ma=max(ma,a[i]);
        }
        int p;
        for(int i=1;i<=n;i++){
            if(a[i]==ma){
                p=i;
                break;
            }
        }
        int l=1;
        int ans=0;
        for(int i=2;i<=p;i++){
            if(a[i]>=a[l]){//比如说1 2 
                l=i;//那么这个1就没什么贡献了 
            }
            else{
                ans+=(a[l]-a[i]);//加贡献 
            }
        }
        int r=n; 
        for(int i=n-1;i>=p;i--){
            if(a[i]>=a[r]){
                r=i;
            }
            else{
                ans+=(a[r]-a[i]);
            }
        }
        cout<<ans<<endl;
    } 

    L:

    在杂志社工作的小鹏在休息日突然接到老板丢过来的文本编辑任务,要求将一串漏洞百出的文本A 编辑为小鹏认为合理的文本B,小鹏一次可以对一个字符进行插入、删除和替换操作,每种操作需要耗费的时间分别对应为xyz分钟,然而小鹏一心只想看TT 分钟后的英雄联盟S10 全球总决赛,亲眼见证最喜欢的大乌龟战队夺冠。问:小明是否可以准时观看比赛?若可以,请告诉小明完成工作后还有多久开始比赛,否则输出比赛已经开始了多久。

    Input

    A

    B

    X Y Z T

    Output

    Yes (or No) 和一个整数(如果时间准时看比赛,请输出Yes 0)

    Samples

    Input Copy
    abc
    adc
    5 3 2 2
    Output
    Yes 0

    Hint

    0<|A|,|B|<6000

    1<x,y,z<10000

    解析:这是一个dp的题,就是这两个字符串可能在更新后不同了,所以就有了

    dp[i][j]=0x3f3f3f;
    dp[i][j]=min(dp[i][j],dp[i-1][j]+y);//删除 有可能不一样长(比如a长) 
    dp[i][j]=min(dp[i][j],dp[i][j-1]+x);//插入 有可能(b长) 

    想想就知道了,第一个是如果a长的话就要删除,看看是不是最长

    第二种就是,如果b长a短的话就是要添加

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=6e3+100;
    char a[maxn];
    char b[maxn];
    int dp[maxn][maxn];
    int x,y,z,t;//插入、删除和替换
    int main(){
        scanf("%s",a+1);
        scanf("%s",b+1);
        scanf("%d%d%d%d",&x,&y,&z,&t);
        int lenn=strlen(a+1);
        int lenm=strlen(b+1);
        for(int i=1;i<=lenm;i++){
            dp[0][i]=i*x; 
        }
        for(int i=1;i<=lenn;i++){
            dp[i][0]=i*y;
        } 
        for(int i=1;i<=lenn;i++){
            for(int j=1;j<=lenm;j++){
                dp[i][j]=0x3f3f3f;
                dp[i][j]=min(dp[i][j],dp[i-1][j]+y);//删除 有可能不一样长(比如a长) 
                dp[i][j]=min(dp[i][j],dp[i][j-1]+x);//插入 有可能(b长) 
                if(a[i]==b[j]){
                    dp[i][j]=min(dp[i][j],dp[i-1][j-1]);
                }
                else{
                    dp[i][j]=min(dp[i][j],dp[i-1][j-1]+z);
                }
            }
        }
        int z=dp[lenn][lenm];
        if(z<=t){
            printf("Yes %d",t-z);
        }
        else{
            printf("No %d",z-t);
        }
    }
  • 相关阅读:
    .net开发微信公众号(2)-验证服务器地址
    [广度遍历和深度遍历]聊聊算法和设计模式
    DDD领域驱动设计之聚合、实体、值对象
    DDD领域驱动设计之运用层代码
    DDD领域驱动设计之领域服务
    DDD领域驱动设计之领域基础设施层
    DDD领域驱动设计实践篇之如何提取模型
    Docker最全教程——从理论到实战(七)
    Docker最全教程——从理论到实战(六)
    Docker最全教程——从理论到实战(五)
  • 原文地址:https://www.cnblogs.com/lipu123/p/13991792.html
Copyright © 2020-2023  润新知