zoukankan      html  css  js  c++  java
  • Codeforces Round #637 (Div. 2)

    A. Nastya and Rice

    题意

    有n粒米,每粒米的重量在((a-b,a+b))之间,有一个袋子,承重在((c-d,c+d))之间,判断是否有可能装下。

    思路

    求出米的重量区间(((a-b)n,(a+b)n)),判断((c-d,c+d))区间是否有交集。

    代码

    #include<iostream>
    #include<string.h>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<string>
    #include<set>
    #include<map>
    using namespace std;
    typedef pair<int,int> PII;
    typedef long long LL;
    int main(){
        int T;
        cin>>T;
        while(T--){
            LL n,a,b,c,d;
            cin>>n>>a>>b>>c>>d;
            LL l1=(a-b)*n,r1=(a+b)*n;
            LL l2=c-d,r2=c+d;
            if(max(l1,l2)<=min(r1,r2)){
                cout<<"Yes"<<endl;
            }
            else cout<<"No"<<endl;
        }
        return 0;
    }
    

    B. Nastya and Door

    题意

    求出在长度为k的区间的左端点l,区间内的peek最多,如果有多个区间peak一样多,输出左端点最小的l,如果(a_i)是peak则(a_i>a_{i-1},a_i>a_{i-1}),区间的边界不可以算peak(题目背景弄那么长,和题意连接牵强...

    思路

    直接求前缀和,枚举每一个区间的左端点l。(注意最坏情况没有peak时,输出最短点时1!

    代码

    #include<iostream>
    #include<string.h>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<string>
    #include<set>
    #include<map>
    using namespace std;
    typedef pair<int,int> PII;
    typedef long long LL;
    int a[200010],f[200010],sum[200010];
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            int n,k;
            memset(f,0,sizeof f);
            memset(sum,0,sizeof sum);
            scanf("%d%d",&n,&k);
            a[0]=a[n+1]=1e9+10;
            for(int i=1;i<=n;++i)
                scanf("%d",&a[i]);
            for(int i=1;i<=n;++i){
                if(a[i]>a[i-1]&&a[i]>a[i+1]){
                    f[i]=1;
                }
                else f[i]=0;
            }
            for(int i=1;i<=n;++i)
                sum[i]=sum[i-1]+f[i];
            int t=0,l=1;
            for(int i=1;i<=n;++i){
                if(sum[i+k-1]-sum[i-1]-f[i]-f[i+k-1]>t){
                    t=sum[i+k-1]-sum[i-1]-f[i]-f[i+k-1];
                    l=i;
                }
            }
            cout<<t+1<<" "<<l<<endl;
        }
        return 0;
    }
    

    C. Nastya and Strange Generator

    题意

    一开始有一个空序列,要求变成一个目标序列,n次操作的步骤如下:
    r数组,(r_j)表示从j到n,a数组中第一个没有填数的下标;
    cnt数组,(cnt_t)表示r数组有t的个数;
    第i次操作选择cnt数组中最大元素的下标t(有多个最大值可以选择任意一个),将i填入(a_t)
    判断n次操作后最终是否可以变成目标序列。

    思路

    每当r中一个数被选择,它就等于它右边的数,右边的数在cnt中出现的次数就++。考虑初始r={1,2,...,n},所以每次被选则的数要么右边没数了,要么右边的数比它大1。

    代码

    #include<iostream>
    #include<string.h>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<string>
    #include<set>
    #include<map>
    using namespace std;
    typedef pair<int,int> PII;
    typedef long long LL;
    int a[100010],n,f[100010];
    bool solve(){
        int tn=n,s=0;
        for(int i=1;i<=n;++i){
            if(f[i]==tn)  tn-=s+1,s=0;
            else if(f[i]+1==f[i+1]) s++;
            else  return false;
        }
        return true;
    }
    int main(){
        int T;
        cin>>T;
        while(T--){
            cin>>n;
            for(int i=1;i<=n;++i)
                cin>>a[i],f[a[i]]=i;
            if(solve()){
                puts("Yes");
            }
            else puts("No");
        }
        return 0;
    }
    

    D. Nastya and Scoreboard

    题意

    有n个数字晶体管,初始时每个晶体管中的某些部分在亮着,求K次点亮操作,使得每个晶体管都是一个数,且组成的十进制数最大。((1≤n≤2000,1≤k≤2000))

    思路

    很显然的01背包。但是由于n很大,最终的答案一定是一个高精度数,那么常数就变得很大。(被Tle过了
    转化一下思路:先找到数字合法方案,再贪心选数字。
    (f[i][j]=1)表示从n到i点亮j次可以使得n到i成为合法的数字,否则(f[i][j]=0).这个过程很容易就不细说了。
    当预处理完成后,判断(f[1][k])是否等于1,如果不等于1,说明误解。
    然后从1到n依次枚举高位,从最大的数开始选,选前判断当前位选这个数下一位到n是否存在合法方案。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int st[10],a[200010],ones[1<<7],n,m;
    void init(){
        for(int i=0;i<(1<<7);++i){
            for(int j=0;j<7;++j){
                if(i&(1<<j)) ones[i]++;
            }
        }
        char s[10][10]={"1110111","0010010","1011101","1011011","0111010",
                        "1101011","1101111","1010010","1111111","1111011"};
        for(int i=0;i<10;++i){      //
            for(int j=0;j<7;++j){
                if(s[i][j]=='1') st[i]|=(1<<j);
            }
        }
        char str[10];
        for(int i=1;i<=n;++i){
            cin>>str;
            for(int j=0;j<7;++j){
                if(str[j]=='1') a[i]|=(1<<j);
            }
        }
    }
    string ans;
    bool f[2010][2010];
    void solve(){
        f[n+1][0]=1;
        for(int i=n;i>=1;--i){
            for(int j=0;j<10;++j){
                if((st[j]&a[i])==a[i]){
                    int t=ones[(st[j]^a[i])];
                    for(int k=t;k<=m;++k){
                        if(f[i+1][k-t]){
                            f[i][k]=1;
                        }
                    }
                }
            }
        }
        if(f[1][m]==0){
            puts("-1");
            return ;
        }
        for(int i=1;i<=n;++i){
            for(int j=9;i>=0;--j){
                if((st[j]&a[i])==a[i]){
                    int t=ones[(st[j]^a[i])];
                    if(f[i+1][m-t]){
                        ans+=char('0'+j);
                        m-=t;
                        break;
                    }
                }
            }
        }
        cout<<ans<<endl;
    }
    int main(){
        cin>>n>>m;
        init();
        solve();
        return 0;
    }
    
  • 相关阅读:
    MeshLab编译理解
    几个经典的数学库之一学习---VCGlib(1)
    开源协议的几种类型认识
    Win & Mac 系统之间U盘传递的U盘文件格式选取问题
    用VS2010编译python2.7的源码
    类之间关系理解:组合>聚合>关联>依赖;实现,继承
    Linux进阶:让效率翻倍的Bash技巧(一)
    Linux下nc命来实现文件传输
    nginx 405 not allowed问题的解决
    vim同时打开多个文件进行编辑
  • 原文地址:https://www.cnblogs.com/jjl0229/p/12767793.html
Copyright © 2011-2022 走看看