zoukankan      html  css  js  c++  java
  • CF595 Div31249A,1249B1,1249B2,1249C1,1249C2,1249D1,1249D2,1249E,1249F)题解

    A:水题,先排序,有相连的输出2,否则输出1.

    #include<bits/stdc++.h>
    using namespace std;
    #define pii pair<int,int>
    #define mkp make_pair
    #define pb push_back
    #define fi first
    #define se second
    typedef long long ll;
    const int INF=0x3f3f3f3f;
    int q,n;
    const int maxn=110;
    int a[maxn];
     
     
    int main()
    {
        scanf("%d",&q);
        while(q--)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;++i) scanf("%d",a+i);
            sort(a+1,a+1+n);
            int cnt=1;
            for(int i=2;i<=n;++i)
            {
                if(a[i]-a[i-1]==1) {cnt=2;break;}
            }
            printf("%d
    ",cnt);
        }
        
        return 0;
    }
    View Code

    B1和B2: 水题:同一个循环里面的步数一样,O(N)跑一遍即可。

    #include<bits/stdc++.h>
    using namespace std;
    #define pii pair<int,int>
    #define mkp make_pair
    #define pb push_back
    #define fi first
    #define se second
    typedef long long ll;
    const int INF=0x3f3f3f3f;
    int q,n;
    const int maxn=2e5+10;
    int p[maxn],cnt[maxn],vis[maxn];
     
     
    int main()
    {
        scanf("%d",&q);
        while(q--)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;++i) scanf("%d",p+i),cnt[i]=vis[i]=0;
            for(int i=1;i<=n;++i)
            {
                if(vis[i]) continue;
                int ans=1,num=p[i];vis[i]=i;
                while(num!=i)
                {
                    num=p[num];
                    vis[num]=i;
                    ans++;
                }
                cnt[i]=ans;
            }
            for(int i=1;i<=n;++i) 
                printf("%d%c",cnt[vis[i]],i==n?'
    ':' ');
        }
        
        return 0;
    }
    View Code

    C1和C2: 水题:很显然>=n的最大的只要把n里面所有的3的幂去除,然后把剩下未选中的挑一个最小的且比去除之后的n大的加入答案就行。注意到样例里面给的最大的那个是3^38.

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll a[40];
    void prework()
    {
        a[0]=1;
        for(int i=1;i<=39;++i) a[i]=a[i-1]*3;
    }
     
    int q;
    ll n,cn;
     
    int main()
    {
        prework();
        scanf("%d",&q);
        while(q--)
        {
            scanf("%lld",&n);
            ll ans=0; cn=n;
            int flag=-1,tmp=-1,tt=0;
            for(int i=38;i>=0;--i) 
            {
                if(n==a[i]){ans=a[i];tt=1;break;}
                if(a[i]<n){tmp=i+1;break;}    
            }
            if(tt){printf("%lld
    ",ans);continue;}
            
            for(int i=tmp-1;i>=0;--i)
            {
                if(n==a[i]){ans+=a[i];tt=1;break;}
                if(n>a[i]) {n-=a[i];ans+=a[i];}
                else flag=i; 
            }
            if(tt){printf("%lld
    ",ans);continue;}
            
            if(flag!=-1)
            {
                for(int i=0;i<flag;++i) ans-=a[i];
                ans+=a[flag];
            }
            else ans=a[tmp];
        
            printf("%lld
    ",ans);
        }
        
        return 0;    
    } 
    View Code

    D1和D2:

    D1可以暴力:set维护答案。

    #include<bits/stdc++.h>
    using namespace std;
    #define pii pair<int,int>
    #define mkp make_pair
    #define pb push_back
    #define fi first
    #define se second
    typedef long long ll;
    const int INF=0x3f3f3f3f;
     
    const int maxn=210;
    int k,n,cnt[maxn],vis[maxn];
    struct Node{
        int l,r,id;
    }p[maxn];
    bool cmp(Node &a,Node &b){return a.r<b.r;}
    vector<Node> v[maxn];
    set<int> st;
     
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;++i)
        { 
            scanf("%d%d",&p[i].l,&p[i].r);p[i].id=i;
            for(int j=p[i].l;j<=p[i].r;++j)
                v[j].push_back(Node{p[i].l,p[i].r,i}),cnt[j]++;
        } 
        //for(int i=1;i<=200;++i) cout<<cnt[i]<<endl;
        for(int i=1;i<=200;++i) 
            sort(v[i].begin(),v[i].end(),cmp);
        for(int i=1;i<=200;++i)
        {
            if(cnt[i]>k) 
            {
                int nn=cnt[i]-k;
                for(int j=v[i].size()-1;j>=0&&nn;--j)
                { 
                    if(vis[v[i][j].id]) continue;
                    st.insert(v[i][j].id),nn--; 
                    vis[v[i][j].id]=1;
                    for(int k=v[i][j].l;k<=v[i][j].r;++k)
                        cnt[k]--; 
                } 
            }
        }
        int len=st.size();
        printf("%d
    ",len);
        set<int>::iterator it;
        for(it=st.begin();it!=st.end();++it)
            printf("%d ",(*it));
        puts("");
        
            
        return 0;
    }
    View Code

    D2用线段树。按照 r 从小到大排序。然后从i 1-n枚举,如果区间最大值<k,则加入该线段,否则该线段必须去掉,加入答案集合里面即可。

    最后依次输出答案;

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+10;
    int res[maxn],ans,s[maxn],add[maxn],x,cnt,k,n,Max;
    struct Node{
        int l,r,id;
        bool operator<(const Node&p)const{
            return r^p.r?r<p.r:l<p.l;
        }
    }a[maxn];
    void pushdown(int l,int r,int rt)
    {
        int mid=l+r>>1;
        add[rt<<1]+=add[rt],add[rt<<1|1]+=add[rt];
        s[rt<<1]+=add[rt],s[rt<<1|1]+=add[rt];
        add[rt]=0;
    }
    void update(int l,int r,int rt,int u,int v)
    {
        if(l>v||r<u) return;
        if(l>=u&&r<=v)
        {
            s[rt]+=x,add[rt]+=x;
            return;
        }
        if(add[rt]) pushdown(l,r,rt);
        int mid=l+r>>1;
        update(l,mid,rt<<1,u,v);
        update(mid+1,r,rt<<1|1,u,v);
        s[rt]=max(s[rt<<1],s[rt<<1|1]);
    }
    void query(int l,int r,int rt,int u,int v)
    { 
        if(l>v||r<u) return;
        if(l>=u&&r<=v)
        { 
            ans=max(ans,s[rt]);
            return;
        }
        if(add[rt]) pushdown(l,r,rt);
        int mid=l+r>>1;
        query(l,mid,rt<<1,u,v);query(mid+1,r,rt<<1|1,u,v);
        s[rt]=max(s[rt<<1],s[rt<<1|1]);
    }
    int main()
    {  
        scanf("%d%d",&n,&k);
        Max=cnt=0;
        for(int i=1;i<=n;++i) 
        {
            scanf("%d%d",&a[i].l,&a[i].r);a[i].id=i; 
            Max=max(Max,a[i].r);    
        }
        
        sort(a+1,a+1+n);x=1;
        for(int i=1;i<=n;++i)
        {
            int u=a[i].l,v=a[i].r; ans=0;
            query(1,Max,1,u,v); 
            if(ans<k) update(1,Max,1,u,v);
            else res[++cnt]=a[i].id;
        }
        printf("%d
    ",cnt);
        sort(res+1,res+1+cnt);
        for(int i=1;i<=cnt;++i) 
            printf("%d%c",res[i],i==cnt?'
    ':' ');
        return 0;
    }
    View Code

    E:水题:DP即可。设f[i][0],f[i][1]表示选择楼梯和电梯的状态,直接按照题意模拟就行。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6+10;
    int a[N],b[N],f[N][2],n,c;
    int main()
    {  
        scanf("%d%d",&n,&c);--n;
        for(int i=1;i<=n;++i) scanf("%d",a+i);
        for(int i=1;i<=n;++i) scanf("%d",b+i);
        f[0][1]=1e9;
        for(int i=1;i<=n;++i) f[i][0]=min(f[i-1][0],f[i-1][1])+a[i],f[i][1]=min(f[i-1][0]+c,f[i-1][1])+b[i];
        printf("0 ");for(int i=1;i<=n;++i) printf("%d ",min(f[i][0],f[i][1])); puts("");
        return 0;
    }
    View Code

    F题:暴力贪心。n<=200直接暴力找从深度为n开始距离k以内的点集和。

    贪心的取比较大的值即可。
    将所有点按照深度从大到小排序,如果当前点点权a[i]大于0,则将距离为k以内的所有点减a[i]
    代表取了当前点,为答案贡献a[i]
    如果下面又扫到大于零的点权,说明那个点比这个大,于是取那个

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+10; 
    int n,k,a[maxn],t,nw,u,v,d[maxn],ans;
    vector<int> g[maxn];
    struct Edge{
        int v,nxt;
    } edge[maxn<<1];
    int head[maxn],tot;
    void AddEdge(int u,int v)
    {
        edge[tot].v=v;edge[tot].nxt=head[u];head[u]=tot++;
        edge[tot].v=u;edge[tot].nxt=head[v];head[v]=tot++;
    }
    void dfs(int x,int fa)
    {
        g[d[x]=d[fa]+1].push_back(x);
        for(int i=head[x],j;~i;i=edge[i].nxt)
            if((j=edge[i].v)!=fa) dfs(j,x);
    }
    void dfs2(int x,int fa,int dep)
    {
        a[x]-=nw;
        if(dep==k) return;
        for(int i=head[x],j;~i;i=edge[i].nxt)
            if((j=edge[i].v)!=fa) dfs2(j,x,dep+1);
    }
    int main()
    {  
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;++i) scanf("%d",a+i),head[i]=-1;
        for(int i=1;i<n;++i) scanf("%d%d",&u,&v),AddEdge(u,v);
        dfs(1,0);
        for(int i=n;i;--i)
            for(int j=0,sz=g[i].size(),x;j<sz;++j)
                if((x=a[g[i][j]])>0) nw=x,ans+=x,dfs2(g[i][j],0,0);
        printf("%d
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    原创 记录一次线上Mysql慢查询问题排查过程
    原创 |我是如何解决POI解析Excel出现的OOM问题的?
    FastJson序列化时候出现了$ref?还不赶紧学习下
    fastjson自定义序列化竟然有这么多姿势?
    SpringBoot2.0整合WebSocket,实现后端数据实时推送!
    SpringMVC+Mybatis 如何配置多个数据源并切换?
    异常: java.security.InvalidKeyException: Illegal key size
    一分钟带你了解下MyBatis的动态SQL!
    一分钟带你了解下Spring Security!
    历时七天,史上最强MySQL优化总结,从此优化So Easy!
  • 原文地址:https://www.cnblogs.com/csushl/p/11729886.html
Copyright © 2011-2022 走看看