zoukankan      html  css  js  c++  java
  • 套题 codeforces 361

    A题((Mike and Cellphone)

    看起来好像需要模拟数字键位的运动,可是,
    只要判断出那些必然YES的数字组合不就好了么

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    using namespace std;
    int vis[10];
    inline bool judge()
    {
        if(vis[9]&&vis[1]) return true;
        if(vis[7]&&vis[3]) return true;
        if(vis[0]&&(vis[1]||vis[2]||vis[3])) return true;
        if((vis[1]||vis[2])&&vis[6]&&vis[7]) return true;
        if((vis[3]||vis[2])&&vis[4]&&vis[9]) return true;
        if(vis[7]&&vis[9]&&vis[2]) return true;
        return false;
    }
    char ch[100];
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            scanf("%s",ch);
            int x;
            memset(vis,0,sizeof(vis));
            for(int i=0;i<n;i++)
            {
                x=ch[i]-'0';
                vis[x]=1;
            }
            if(judge())
            {
                printf("YES
    ");
            }
            else printf("NO
    ");
        }
        return 0;
    }
    View Code

    B题((Mike and Shortcuts)
    题意:对于n个点,可以从1开始直接走过去,代价是abs(x-1),也可以通过某种捷径而到,代价是1
    解题:难点在于建图,每个点之间都连通,难道要建n^2条边?
    1.在不考虑捷径的情况下,每两个点之间的距离是两者之差的绝对值
    2.任意两点没有必要都建一条边使得他们直接相连,对于任意的一个点,只要相邻的两个
    点与它建一条代价为1的边,这样任意两点都能够间接相连,而且代价累加起来正好是距离。
    3.最后再加上捷径,最多有n条,总共会有3*n条边,由于不存在负权回路,使用DIJKSTRA+优先队列
    优化,时间复杂度是O(ElogE).

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <queue>
    #include <vector>
    using namespace std;
    const int Max=200000+10;
    int abs(int x) {return x>=0?x:-x;}
    int n,m;
    struct Edge{
    int from,to,dist;
    Edge(int u,int v,int d):from(u),to(v),dist(d){}
    };
    vector <Edge> edges;
    vector <int>  G[Max];
    int d[Max];
    void Init()
    {
        for(int i=0;i<=n;i++) G[i].clear();
        edges.clear();
    }
    void AddEdge(int from,int to,int dist)
    {
        edges.push_back(Edge(from,to,dist));
        m=edges.size();
        G[from].push_back(m-1);
    }
    struct node
    {
        int d,u;
        node(int dd,int uu):d(dd),u(uu){};
        bool operator < (const node & rhs) const {
        return d>rhs.d;
        }
    };
    const int INF=0x3f3f3f3f;
    bool done[Max];
    void Dijkstra(int s)
    {
        priority_queue<node>Q;
        for(int i=1;i<=n;i++) d[i]=INF;
        d[s]=0;
        memset(done,0,sizeof(done));
        Q.push(node(0,s));
        while(!Q.empty())
        {
            node x=Q.top();Q.pop();
            int u=x.u;
            if(done[u]) continue;
            done[u]=true;
            for(int i=0;i<G[u].size();i++)
            {
                Edge &e=edges[G[u][i]];
                if(d[e.to]>d[u]+e.dist)
                {
                    d[e.to]=d[u]+e.dist;
                    Q.push(node(d[e.to],e.to));
                }
            }
        }
    }
    int main()
    {
        while(~scanf("%d",&n))
        {
           int x;
           Init();
           for(int i=1;i<=n;i++)
           {
               scanf("%d",&x);
               AddEdge(i-1,i,1);
               AddEdge(i+1,i,1);
               AddEdge(i,x,1);
           }
           Dijkstra(1);
           for(int i=1;i<=n;i++)
           {
               if(i!=1) printf(" ");
               printf("%d",d[i]);
           }
           puts("");
        }
        return 0;
    }
    View Code

    C题(Mike and Chocolate Thieves)
    要求一个四元组,并且这个四元组成k倍关系。
    可知n越大,种数越多,且种类数取决于k。
    对于这样一个有序关系,可以使用二分查找

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    LL n;
    LL cacu(LL x)
    {
        LL sum=0;
        for(LL i=2;i<=1e6;i++)
        {
            if(i*i*i>x) break;
            sum+=x/(i*i*i);
        }
        return sum;
    }
    int main()
    {
        while(~scanf("%I64d",&n))
        {
            LL l=0,r=1e18,m;
            while(l<=r)
            {
                m=(l+r)>>1;
                if(cacu(m)>=n)  r=m-1;
                else         l=m+1;
            }
            if(cacu(r+1)!=n) puts("-1");
            else printf("%I64d
    ",r+1);
        }
        return 0;
    }
    View Code

    D题(Friends and Subsequences)
    对于每个max(ai)==min(bj)
    枚举所有的左区间,
    max(ai)是递增的,min(bj)是递减的
    因此对max(ai)-min(bj)可以进行二分查找
    二分查找满足条件的下界和上界
    RMQ可以使用ST算法实现

    #include <bits/stdc++.h>
    using namespace std;
    const int N=2e5+10;
    int A[N],B[N];
    int mn[N][30],mx[N][30];
    void RMQ_init(int n)
    {
        for(int i=1;i<=n;i++) mx[i][0]=A[i],mn[i][0]=B[i];
        for(int j=1;(1<<j)<=n;j++)
        {
            for(int i=1;i+(1<<j)-1<=n;i++)
            {
                mx[i][j]=max(mx[i][j-1],mx[i+(1<<(j-1))][j-1]);
                mn[i][j]=min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]);
            }
        }
    }
    int RMQ(int L,int R,int flag)
    {
        int k=0;
        while((1<<(k+1))<=R-L+1) k++;
        if(flag)
            return max(mx[L][k],mx[R-(1<<k)+1][k]);
        else
            return min(mn[L][k],mn[R-(1<<k)+1][k]);
    }
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            for(int i=1;i<=n;i++) scanf("%d",&A[i]);
            for(int i=1;i<=n;i++) scanf("%d",&B[i]);
            RMQ_init(n);
            long long sum=0;
            for(int i=1;i<=n;i++)
            {
                int l,r,mid,ansr,ansl,ma,mb;
                ansl=ansr=-1;
                l=i;r=n;
                while(l<=r)
                {
                    mid=l+(r-l)/2;
                    ma=RMQ(i,mid,1);mb=RMQ(i,mid,0);
                    if(ma==mb) l=mid+1,ansr=mid;
                    else
                    if(ma>mb) r=mid-1;
                    else l=mid+1;
                }
                l=i;r=n;
                while(l<=r)
                {
                    mid=l+(r-l)/2;
                    ma=RMQ(i,mid,1);mb=RMQ(i,mid,0);
                    if(ma==mb) r=mid-1,ansl=mid;
                    else
                    if(ma>mb) r=mid-1;
                    else l=mid+1;
                }
                if(ansl==-1||ansr==-1) continue;
                sum+=ansr-ansl+1;
            }
            printf("%I64d
    ",sum);
        }
        return 0;
    }
    View Code

    E题

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=2e5+10;
    const int MOD=1e9+7;
    LL fact[N];
    LL qpow(LL x,LL k)
    {
        LL base=x,ans=1;
        while(k)
        {
            if(k&1) ans=(ans*base)%MOD;
            base=(base*base)%MOD;
            k>>=1;
        }
        return ans;
    }
    LL inv(LL x)
    {
        return qpow(x,MOD-2);
    }
    LL C(int n,int k)
    {
        LL ans=fact[n]*inv(fact[k])%MOD*inv(fact[n-k])%MOD;
        return ans;
    }
    map<int,int>book;
    int main()
    {
        int n,k,l,r,ans,add,dist;
        cin>>n>>k;
        fact[0]=1;
        for(int i=1;i<=n;i++) fact[i]=(fact[i-1]*i)%MOD;
        for(int i=0;i<n;i++)
        {
            cin>>l>>r;
            book[l]++;
            book[r+1]--;
        }
        ans=add=0;
        l=book.begin()->first;
        map<int,int>::iterator it;
        for(it=book.begin();it!=book.end();it++)
        {
            dist=it->first-l;
            if(add>=k) ans=(ans+C(add,k)*dist)%MOD;
            add+=it->second;
            l=it->first;
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    Android:RelativeLayout相对布局(转)
    Android:LayoutInflater作用及使用(转)
    keepalive安装配置
    nginx 多级7层代理安装配置
    k8s使用cephfs
    haproxy安装及配置
    通过nodeSelector配置项实现pod部署至指定node
    SFTP使用key文件登录
    k8s使用ceph存储
    nginx开启gzip压缩后导致apk包下载不能正常安装
  • 原文地址:https://www.cnblogs.com/zsyacm666666/p/5939160.html
Copyright © 2011-2022 走看看