Mail.Ru Cup 2018 Round 2 ABC

A. Metro 直接模拟

题意:有两条道路(来回) 各有n个站,A住在1站 B住在S站,有些站还没开通则为 0 ,开通则为 1;

问 A能否从1站到达S站(第一条道路只能向东走,可以转站到第二条道路,然往回走);

#include<bits/stdc++.h>
using namespace std;
int a[1002],b[1002];
int main()
{
    int n,s;
    while(~scanf("%d %d",&n,&s))
    {
        for(int i=1;i<=n;i++)
            {scanf("%d",&a[i]);}
        for(int i=1;i<=n;i++)
           {
               scanf("%d",&b[i]);}
        if(a[1]==0) {
            printf("NO\n");continue;
        }
        if(a[s]==1)
        {
            printf("YES\n");continue;
        }
        if(b[s]==0)
        {
            printf("NO\n");continue;
        }
        else{int f=1;
            for(int i=s;i<=n;i++)
            if(a[i]==1&&b[i]==1) {
                f=0;break;
            }
            if(f==0) printf("YES\n");
            else printf("NO\n");
        }
    }
}

B - Alice and Hairdresser  小思维

题意:给出一串 n 个数的数列,有 m 个询问 

0  则询问当前数列中有多少段子串其数值全部高于k;

1  给a[i]加上y;

#include<bits/stdc++.h>
using namespace std;
int a[100005],b[100005];
int main()
{
    int n,m,k;
    while(~scanf("%d%d%d",&n,&m,&k))
    {
        int ans=0;
        for(int i=1;i<=n;i++)
        {scanf("%d",&a[i]);if(a[i-1]<=k&&a[i]>k)ans++;}
        while(m--)
        {
            int x;
            scanf("%d",&x);
            if(x==0){
                printf("%d\n",ans);continue;
            }
            else{
                int x,y;
                scanf("%d%d",&x,&y);
                if(a[x]>k) continue;
                else{
                        a[x]+=y;
                    if(a[x]>k&&a[x-1]>k&&a[x+1]>k) ans--;
                    if(a[x]>k&&a[x-1]<=k&&a[x+1]<=k) ans++;
                }
            }
        }
    }
}

C - Lucky Days  

#include<cstring>
#include<algorithm>
#include<cstdio>
 
using namespace std;
 
int gcd(int a,int b)
{
    if(!b) return a;
    else return gcd(b,a%b);
}
 
int solve(int a,int b,int x,int y){ ///计算两个区间公共的数
 
    return min(b,y)-max(a,x)+1;
}
 
int main()
{
    int la,ra,ta,lb,rb,tb;
 
    while(~scanf("%d%d%d%d%d%d",&la,&ra,&ta,&lb,&rb,&tb))
    {
 
        la++,ra++,lb++,rb++;
 
        int item=gcd(ta,tb); 
 
        if(ta==tb){ ///两个区间已经最靠近了,故直接算就行了
            printf("%d\n",solve(la,ra,lb,rb));
            continue;
        }
        int m,ans;
        if(ra<=rb){
             m=(rb-ra)/item;
            la+=m*item;
            ra+=m*item;
             ans=0; ///注意此处初始化为0,
             
///因为我们加的不一定刚好对齐,只需在不超过(尽量靠近)另一个区间和超过(尽量靠近)另一个区间之间选一个最大值就好了
            
            ans=max(ans,solve(la,ra,lb,rb)); 
 
            ans=max(ans,solve(la+item,ra+item,lb,rb));
        }
        else{
             m=(ra-rb)/item;
            lb+=m*item;
            rb+=m*item;
             ans=0;
 
            ans=max(ans,solve(la,ra,lb,rb));
 
            ans=max(ans,solve(la,ra,lb+item,rb+item));
        }
 
        printf("%d\n",ans);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41668093/article/details/84189504
今日推荐