Codeforces Round #562 (Div. 2)(A,B,C题解)

7 篇文章 0 订阅
6 篇文章 0 订阅

题目链接

A Circle Metro

题意:现在有1-n个车站,有两个平行的轨道,一个轨道的列车是按车站的升序跑(1->n),另一个轨道是按降序跑(n->1)。现在有两个人,现在两个人分别乘两个轨道的列车,给出两个人的乘车起点和终点,问两个人中途是否能在同一个车站相遇,若列车跑到1或n还没有到两个人的终点,则又从1或n开始跑,直到到两个人的终点。

题解:首先判断两个人的起点和终点是否相同,相同直接输出。因为n只有100,所以直接循环就行了,但是循环最多两次,因为循环两次后要是还没有遇到后面肯定不会遇到了。

#include <iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<stack>
#include<string>
const int maxn=1e5+5;
const int mod=10007;
const int inf=1e9;
const long long onf=1e18;
#define me(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x&(-x)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI 3.14159265358979323846
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
int main()
{
    int n,a,x,b,y;
    cin>>n>>a>>x>>b>>y;
    if(a==b||x==y){
        puts("YES");
    }else{
        int lena=0,lenb=0;
        int i=a,j=b;
        while(1){
            if(i==n+1)
                i=1,lena++;
            if(j==0)
                j=n,lenb++;
            if(i==j){
                puts("YES");
                return 0;
            }
            if(lena>2||lenb>2||i==x||j==y)
                break ;
            i++,j--;
        }
        puts("NO");
    }
    return 0;
}

B. Pairs

题意:现在给出m对数,每对数的两个数不相同,且都在1-n的范围内,现在要你求,是否有两个数在这m对,每对数中都有出现。

题解:因为是找两个数,在每对数中都有出现,这样在第一对数中,总有一个数在后面也要出现的,所以就固定其中一个数,来找第二个数,找第二个数的时候,记录出现次数,要是当前对数出现我们固定的数,就不加,要是未出现,就将两个数分别+1,然后看是否有某个数出现的次数等于固定的数未出现对数的数目。

#include <iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<stack>
#include<string>
const int maxn=3e5+5;
const int mod=10007;
const int inf=1e9;
const long long onf=1e18;
#define me(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x&(-x)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI 3.14159265358979323846
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
int a[maxn][2],n,m;
bool check(int x){
    int sum[maxn];me(sum,0);
    int s=0;
    for(int i=0;i<m;i++){
        if(a[i][0]!=x&&a[i][1]!=x){
            sum[a[i][0]]++,sum[a[i][1]]++;
            s++;
        }
    }
    for(int i=1;i<=n;i++){
        if(sum[i]==s)
            return true;
    }
    return false ;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
        scanf("%d%d",&a[i][0],&a[i][1]);
    if(check(a[0][0])||check(a[0][1]))
        puts("YES");
    else
        puts("NO");
    return 0;
}

C. Increasing by Modulo

题意:有一个序列,现在给出一种操作,每次可以选k个数进行这种操作,现在问你最少操作多少次,能使这个序列变成一个不下降序列。

题解:虽然每次都可以选择k个数来执行这个操作,但是选哪几个数就是问题,和我们到底应该加到哪个数上,这样我们就可以二分修改次数,然后在遍历每个数,如果这个数需要操作,就加上x,然后一直改下去,要是当前数不需要改,则直接跳过,但是要注意维护当前最大值。

#include <iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<stack>
#include<string>
const int maxn=3e5+5;
const int mod=10007;
const int inf=1e9;
const long long onf=1e18;
#define me(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x&(-x)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI 3.14159265358979323846
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
int a[maxn],n,m;
bool check(int x){
    int Max=0;
    for(int i=1;i<=n;i++){
        if(a[i]<=Max){
            if(Max-a[i]>x)
                return false ;
        }else{
            int temp=m-a[i]+Max;///当前数要是加上x取模变小了,则不能把它当做当前最大值
            if(temp>x)
                Max=a[i];
        }
    }
    return true ;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    int ans=m;
    int l=0,r=m;
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid)){
            ans=mid;
            r=mid-1;
        }else
            l=mid+1;
    }
    printf("%d\n",ans);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值