题目链接
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;
}