• Codeforces Round #562 (Div. 2)


    A. Circle Metro

    题意:一个车站共有n个点  首位连成一个环 也就是1和n相邻   一辆车从x1开始向y1顺时针开   一辆车从x2开始逆时针开

    问是否有一个时刻 两辆车在同一个车站

    签到模拟题:

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    #define lson l,m,pos<<1
    #define rson m+1,r,pos<<1|1
    const int N=100000;
    
    int main()
    {
        int n,x1,x2,y1,y2;
        cin>>n>>x1>>y1>>x2>>y2;
        if(x1==x2){cout<<"YES";return 0;}
    
        while(1)
        {
            x1++;if(x1==n+1)x1=1;
            x2--;if(x2==0)x2=n;
            if(x1==x2){cout<<"YES";return 0;}
            if(x2==y2)break;
            if(x1==y1)break;
        }
        cout<<"NO";
        return 0;
    }
    View Code

    B. Pairs  (30000 2s)

    题意:给出n对数字   试问是否存在两个数x、y  使得任意一对数  这一对数其中至少有一个和x或y相等

    比赛的时候一直在想匈牙利算法  不过就算匈牙利能做时间应该也不允许)

    直接暴力:当两队数完全不一样的时候 此时如果有解 答案肯定在这四个数之中

     

    120ms

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    #define lson l,m,pos<<1
    #define rson m+1,r,pos<<1|1
    const int N=300000+5;
    int num[N][2],n,m,a,b,c,d,x,y;
    bool ok1(int x,int y)
    {
        rep(i,1,m)
        if(num[i][0]!=x&&num[i][0]!=y&&num[i][1]!=x&&num[i][1]!=y   )
        return 0;
        return 1;
    }
    int main()
    {
        RII(n,m);
        RII(a,b);
        num[1][0]=a;num[1][1]=b;
        if(m==1||m==2){cout<<"YES";return 0;}
        int ok=1;
        rep(i,2,m)
        {
            RII(x,y);
            num[i][0]=x;num[i][1]=y;
            if(a!=x&&a!=y&&b!=x&&b!=y)
            {
                ok=0;c=x;d=y;
            }
        }
        if(ok){cout<<"YES";return 0;}
        if(ok1(a,c)||ok1(a,d)||ok1(b,c)||ok1(b,d)){cout<<"YES";return 0;}
    
        cout<<"NO";
        return 0;
    }
    View Code

    还有一种更加巧妙而且好打的方法(智商又一次被碾压了)

    显然 x y 肯定有一个出自 第一对的 第一个数字或者第二个数字

    先假设有x    遍历的时候忽略有x的数对   然后看剩下的数对是否有一个共同值(用一个计数数组记录即可)

    然后对y再进行一次

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    #define lson l,m,pos<<1
    #define rson m+1,r,pos<<1|1
    const int N=300000+5;
    
    int n,m,cnt,num[N];
    struct numm
    {
        int x,y;
    }s[N];
    
    int main()
    {
        RII(n,m);
        RII(s[1].x,s[1].y);
        rep(i,2,m)
        {
            RII(s[i].x,s[i].y);
            if(s[i].x==s[1].x||s[i].y==s[1].x)continue;
            cnt++;
            num[s[i].x]++,num[s[i].y]++;
        }
        bool ok=0;
        rep(i,1,n)if(num[i]==cnt){ok=1;break;}
        CLR(num,0);
        if(ok){cout<<"YES";return 0;}
        cnt=0;
        rep(i,2,m)
        {
            if(s[i].x==s[1].y||s[i].y==s[1].y)continue;
            cnt++;
            num[s[i].x]++;num[s[i].y]++;
        }
        rep(i,1,n)if(num[i]==cnt){ok=1;break;}
        if(ok)puts("YES");
        else puts("NO");
    
        return 0;
    }
    View Code

    跑出来速度居然差不多。。。

     C. Increasing by Modulo**

    题意:给定一个长度为n的序列  和一个模数m  有一种操作: 选择1-n 任意几个位置  让该位置的数+1 (要%m) 

    问做少几次操作使得该序列成为不下降序列

    各种模拟+贪心 过不了QAQ

    这种情况下可以二分答案  在确定答案的情况下贪心策略就十分明显了

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    #define lson l,m,pos<<1
    #define rson m+1,r,pos<<1|1
    const int N=300000+5;
    int a[N],n,m,L,R,ans,mid;
    
    bool check(int cnt)
    {
        int last=0;
        rep(i,1,n)
        {
            if(a[i]==last)continue;
            int temp=a[i]+cnt;temp%=m;
            if(temp>a[i])
            {
                if(last<a[i]){last=a[i];}
                else if(last>temp){return 0;}
            }
            else if(temp<a[i]&&last<a[i]&&last>temp)
                last=a[i];
            else if(temp==a[i])
            {
                if(last>a[i])return 0;
                else last=a[i];
            }
        }
        return 1;
    }
    int main()
    {
        RII(n,m);
        rep(i,1,n)RI(a[i]);
        L=0,R=m;
        while(L<=R)
        {
            int mid=(L+R)>>1;
            if(check(mid))ans=mid,R=mid-1;
            else L=mid+1;
        }
        cout<<ans;
        return 0;
    }
    View Code

     check函数写的太挫了 

    仔细想一下一共有6中状态

    其中一种直接 结束

    两种改last

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    #define lson l,m,pos<<1
    #define rson m+1,r,pos<<1|1
    const int N=300000+5;
    int a[N],n,m,L,R,ans,mid;
    
    bool check(int cnt)
    {
        int last=0;
        rep(i,1,n)
        {
            if(last>a[i]+cnt)return 0;
            else  if(a[i]>last&&(a[i]+cnt)<m||a[i]>last&&(a[i]+cnt)%m<last)last=a[i];
        }
        return 1;
    }
    int main()
    {
        RII(n,m);
        rep(i,1,n)RI(a[i]);
        L=0,R=m;
        while(L<=R)
        {
            int mid=(L+R)>>1;
            if(check(mid))ans=mid,R=mid-1;
            else L=mid+1;
        }
        cout<<ans;
        return 0;
    }
    View Code

    D. Good Triple**

    题意:英文比较好懂就不解释了   主要就是求满足条件的 对的数量

    可以枚举左指针  累加每个左指针的对数 这样就不会遗漏了

    贪心找到最短的满足条件的右指针(贪心) 然后其右边的(包含该)都能和该左指针组成一个答案

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    #define lson l,m,pos<<1
    #define rson m+1,r,pos<<1|1
    const int N=300000+5;
    string s;
    int n,last;
    ll ans;
    
    int main()
    {
        cin>>s;
        n=s.size();
        last=n;
    
        repp(i,n-1,0)
        {
            for(int k=1;i+2*k<n;k++)//其实可以右界可以改成last更快 下面的代码也可以简化
            {
                if(s[i]==s[i+k]&&s[i+k]==s[i+2*k])//找到第一个就退出
                {
                    int temp=i+2*k;
                    if(temp<=last){last=temp;break;}
                    if(temp>last){break;}
                }
            }
            ans+=n-last;//其实是n-1 - last +1
        }
        cout<<ans;
        return 0;
    }
    View Code

     

     

     

     

     

  • 相关阅读:
    [JS]手写动画最小时间间隔设置
    [CSS3]chrome浏览器中支持汉字的最小像素是12px,如何让显示更小的字体
    [HTML,CSS]div+css垂直水平居中
    promise经典题目
    HTML5新兴API
    使用MessageChannel(消息通道)进行深拷贝
    原生js手写Promise
    github图片显示不出来-已解决
    前端原生js加密解密
    vue-cli3前端工程静态文件下载
  • 原文地址:https://www.cnblogs.com/bxd123/p/10941045.html
Copyright © 2020-2023  润新知