• 2019-2020Nowcoder Girl初赛 题解


    题目都不是很难,就是最后一题有点毒瘤

    第一题:牛妹爱整除

    这个你把一个进制数进行拆分,拆分成若干位,然后在取模,这样会发现如果是x进制的数,那么对x+1这个进制转化即满足条件。

    举个例子:一个x进制数abc  a*x*x+b*x+c

    那么(a*x*x+b*x+c)%k  满足于 (a+b+c) 相等

    则x=k+1,那么x%k==1  所以 a*(x%k)*(x%k)%k+b*(x%k)%k+c%k==(a+b+c)%k

    代码很简单,有需求可以直接去牛客找

    第二题:吃桃

    这个是一个树的题目,直接dfs就可以解决,算是dp吧。

    首先dfs找到深度,然后在找深度的同时把路径记录下来,最后输出,

    为了保证小的先选可以先拍个序。

    第三题:背包问题

    这个是一个很裸的背包。

    dp[j]表示价值为 j 的物品,可以占的最多的背包体积

    第四题:泡面

    不知道自己怎么就过了,之前cf有一个差不多的题目(我之前以为差不多),后来发现是两个不一样的题目。

    但是比赛的时候并没有发现,然后我按照我的印象写了,居然A了,因为我写出bug了,但是这个bug好像很合适这个题目,谜之A了。。。

    赛后重新写了一次。

    这个就是一个模拟,用个优先队列模拟就可以了。

    注意开longlong

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn=1e5+5;
    typedef long long ll;
    struct node{
        ll id,val;
        node(ll id=0,ll val=0):id(id),val(val){}
        bool operator<(const node &a)const{
            return a.id<id;
        }
    }a[maxn];
    bool cmp(node a,node b){
        return a.val<b.val;
    }
    priority_queue<node>que;
    ll ans[maxn];
    int main(){
        ll n,p,x;
        scanf("%lld%lld",&n,&p);
        for(int i=1;i<=n;i++) {
            scanf("%lld",&x);
            a[i]=node(i,x);
        }
        sort(a+1,a+1+n,cmp);
        ll nowtime=a[1].val,now=2;
        while(!que.empty()) que.pop();
        que.push(a[1]);
        while(!que.empty()){
            nowtime+=p;
            node u=que.top();que.pop();
            ans[u.id]=nowtime;
            while(now<=n&&a[now].val<=nowtime){
                que.push(a[now]);
                now++;
            }
            if(que.empty()&&now<=n){
                nowtime=a[now].val;
                que.push(a[now]);
                now++;        
            }
        }
        for(int i=1;i<=n;i++) printf("%lld ",ans[i]);
        printf("
    ");
        return 0;
    }
    泡面

    cf和这个很像的题目

    https://codeforces.com/contest/1248/problem/E

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <algorithm>
    #include <map>
    #include <iostream>
    #include <cstdlib>
    #include <stack>
    #define inf 0x3f3f3f3f
    #define LL long long 
    #define inf64 0x3f3f3f3f3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5 + 10;
    struct node{
        int id;
        ll tim;
        node(int id=0,ll tim=0):id(id),tim(tim){}
        bool operator<(const node&a)const{
            return a.id<id;
        }
    }a[maxn];
    queue<node>que;
    priority_queue<node>prique;
    int mins[maxn*4];
    void build(int id,int l,int r){
        mins[id]=inf;
        if(l==r) return ;
        int mid=(l+r)>>1;
        build(id<<1,l,mid);
        build(id<<1|1,mid+1,r);
    }
    void push_up(int id){
        mins[id]=min(mins[id<<1],mins[id<<1|1]);
    }
     
    void update(int id,int l,int r,int pos,int val){
        if(l==r){
            mins[id]=val;
            return ;
        }
        int mid=(l+r)>>1;
        if(pos<=mid) update(id<<1,l,mid,pos,val);
        else update(id<<1|1,mid+1,r,pos,val);
        push_up(id);
    }
    bool cmp(node a,node b){
        if(a.tim==b.tim) return a.id<b.id;
        return a.tim<b.tim;
    }
    ll ans[maxn];
    int main(){
        int n,p;
        scanf("%d%d",&n,&p);
        build(1,1,n);
        for(int i=1;i<=n;i++) scanf("%lld",&a[i].tim),a[i].id=i;
        sort(a+1,a+1+n,cmp);
        
        while(!que.empty()) que.pop();
        while(!prique.empty()) prique.pop();
        
        int now=1;
        ll nowtime=a[now].tim;
        que.push(a[now]);
        update(1,1,n,a[now].id,a[now].id);now++;
        
        while(now<=n&&a[now].tim<=nowtime+p){
            if(a[now].id<=mins[1]) {
                que.push(a[now]);
                update(1,1,n,a[now].id,a[now].id);now++;
            }
            else prique.push(a[now]),now++;
        }
        
        while(now<=n||!que.empty()||!prique.empty()){
            while(!prique.empty()){
                node u=prique.top();
                if(u.id<=mins[1]){
                    prique.pop();
                    que.push(u);
                    update(1,1,n,u.id,u.id);
                }
                else break;
            }
            while(now<=n&&a[now].tim<=nowtime+p){
                if(a[now].id<=mins[1]) {
                    que.push(a[now]);
                    update(1,1,n,a[now].id,a[now].id);now++;
                }
                else prique.push(a[now]),now++;
            }
            if(!que.empty()){
                int u=que.front().id;que.pop();
                ans[u]=nowtime+p;
                update(1,1,n,u,inf);
            }
            nowtime+=p;
            if(que.empty()&&prique.empty()&&now<=n) nowtime=a[now].tim;
        }
        for(int i=1;i<=n;i++) printf("%lld ",ans[i]);
        printf("
    ");
        return 0;
    }
    E - Queue in the Train

    第五题:伪直径

    这个题目如果你之前碰到过求直径的题目就可以很快的反应过来,但是如果没有呢,就可能需要思考一会吧。

    而且这个题目名字已经给了很大的提示了,所以还是很好写的。

    答案就是直径减一

    怎么求直径呢?这可以从紫书上看

    就是两次dfs

    就是随便找一个点然后找到最深的叶子节点,然后从这个叶子节点找到最深的另一个叶子节点就可以了。

    第六题:最大最小差

    这个题目好毒瘤

    比赛的时候没有写出来

    然后赛后,用线段树+二分写了一次,tle 3分

    然后问了一个oi dalao,学习了一下双指针+st表的写法,依旧tle,但是 18分

    最后加了各种优化,19分 tle

    最后学会了一种超级厉害的快读,终于A了,oi的快读真强。

    好像还可以用单调队列+双指针写,但是好难写,我不会。。。

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    # define getchar() (S==T&&(T=(S=BB)+fread(BB,1,1<<20,stdin),S==T)?EOF:*S++)
    char BB[1 << 20], *S = BB, *T = BB;
    using namespace std;
    const int maxn=1e6+5;
    typedef long long ll;
    int maxsum[maxn][22],minsum[maxn][22],a[12][maxn],v[12],f[maxn],w[30];
    void init(int n){
        for(int i=1;i<maxn;i++) f[i]=(log(i*1.0)/log(2.0));
        for(int i=0;i<30;i++) w[i]=(1<<i);
    }
    void RMQ(int id,int n) {
        for(int i=1;i<=n;i++){
            maxsum[i][0]=a[id][i];
            minsum[i][0]=a[id][i];
        }
        for (int i = 1; i < 20; i++) {
            for (int j = 1; j <= n; j++) {
                if (j + w[i] - 1 <= n) {
                    maxsum[j][i] = max(maxsum[j][i - 1], maxsum[j + w[i-1]][i - 1]);
                    minsum[j][i] = min(minsum[j][i - 1], minsum[j + w[i-1]][i - 1]);
                }
            }
        }
    }
      
    int st(int x,int y){
        int k=f[y-x+1];
        int maxnum = max(maxsum[x][k], maxsum[y - w[k] + 1][k]);
        int minnum = min(minsum[x][k], minsum[y - w[k] + 1][k]);
        int ans = maxnum - minnum;
        return ans;
    }
    int L[maxn],R[maxn];
    int read()
    {
        int x=0;
        char c=getchar();
        while (!isdigit(c)) c=getchar();
        while (isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
        return x;
    }
     
    inline void write(ll X) {
        if (X < 0) { putchar('-'); X = ~(X - 1); }
        int s[20], top = 0;
        while (X) { s[++top] = X % 10; X /= 10; }
        if (!top) s[++top] = 0;
        while (top) putchar(s[top--] + '0');
        putchar('
    ');
    }
      
    int main(){
        int n,t;
        n=read();
        t=read();
        init(n);
        for(int i=1;i<=t;i++) v[i]=read();
        for(int i=1;i<=t;i++){
            for(int j=1;j<=n;j++){
                a[i][j]=read();
            }
        }
        ll ans=0;
        memset(R,inf,sizeof(R));
        for(int i=1;i<=t;i++){
            RMQ(i,n);
            int p1=1,p2=1;
            for(int j=1;j<=n;j++){
                while(p1<=j&&st(p1,j)>v[i]) p1++;
                while(p2+1<=j&&st(p2+1,j)>=v[i]) p2++;
                  
                if(st(p1,j)!=v[i]) L[j]=inf;
                else L[j]=max(L[j],p1);
                if(st(p2,j)!=v[i]) R[j]=0;
                else R[j]=min(R[j],p2);
            }
        }
        for(int i=1;i<=n;i++){
            if(L[i]<=R[i]) ans+=R[i]-L[i]+1;
        }
    //    printf("%lld
    ",ans);
        write(ans);
        return 0;
    }
    快读好厉害
  • 相关阅读:
    sql server的for xml path与变通的行转列
    nginx产生【413 request entity too large】错误的原因与解决方法
    spring的15个经典面试题
    数据库死锁预防规范
    服务端高并发分布式架构的演进
    后端接口统一返回响应对象
    数据库的dml、ddl和dcl的概念
    [na]ip routing&no ip routing
    [na]一站式学习wireshark
    [na]tcpdump参数应用参考
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/12030689.html
Copyright © 2020-2023  润新知