A. Circle Metro
直接模拟即可。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,a,x,b,y;
cin>>n>>a>>x>>b>>y;
for(int i=1;i<=300;i++){
if(a<n) a++;
else a=1;
if(b>1) b--;
else b=n;
if(a==b){
cout<<"YES"<<endl;return 0;
}
if(a==x||b==y) break;
}
cout<<"NO"<<endl;
return 0;
}
B. Pairs
题意:
对于给定的 m m m对 < a i , b i > <a_i,b_i> <ai,bi>,判断是不是每一对至少存在一个数是 x x x或 y y y。
思路:
先根据 a 1 , b 1 a_1,b_1 a1,b1推出 x x x,然后往下推出 y y y,然后判断可行性。
#include<bits/stdc++.h>
using namespace std;
const int N = 4000000;
int a[N],b[N],num[N];
int n,m;
bool check(int x){
int id;
for(int i=1;i<=m;i++){
if(a[i]==x||b[i]==x) continue;
else{
id=i;break;
}
}
int y1=a[id];int y2=b[id];
int y=-1;
for(int i=id;i<=m;i++){
if(a[i]==x||b[i]==x) continue;
else if(a[i]==y1||b[i]==y1){
if(a[i]+b[i]!=y1+y2){
y=y1;break;
}
}
else if(a[i]==y2||b[i]==y2){
if(a[i]+b[i]!=y1+y2){
y=y2;break;
}
}
else{
return 0;
}
}
if(y==-1) return 1;
for(int i=1;i<=m;i++){
if(a[i]==x||a[i]==y||b[i]==x||b[i]==y) continue;
else return 0;
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++) cin>>a[i]>>b[i];
if(check(a[1])||check(b[1])){
cout<<"YES"<<endl;
}
else cout<<"NO"<<endl;
return 0;
}
C. Increasing by Modulo
题意:
现在有一个长度为
n
n
n的数组,每个数的范围为
[
0
,
m
−
1
]
[0,m-1]
[0,m−1],现在你可以执行若干次下列操作:
选择若干个数,然后把每个数
a
x
a_x
ax变为
(
a
x
+
1
)
(a_x+1)
(ax+1)%
m
m
m,求最少的操作次数。
思路:
二分操作次数,当更新到 a i a_i ai时,如果 a i a_i ai小于当前最大值,判断操作 k k k次是否可行。如果 a i a_i ai大于等于当前最大值,就把 a i a_i ai变成大于当前最大值的最小的数,同时更新最大值即可。复杂度 O ( n ∗ l o g ( m ) ) O(n*log(m)) O(n∗log(m)).
#include<bits/stdc++.h>
using namespace std;
const int N = 4000000;
int n,a[N],m;
bool check(int k){
int preMAX=0;
for(int i=1;i<=n;i++){
if(a[i]<preMAX){
if(preMAX-a[i]>k) return 0;
}
else{
if(a[i]+k<=m-1) preMAX=a[i];
else{
if((a[i]+k)%m<preMAX) preMAX=a[i];
}
}
}
return 1;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
int l=0;int r=m;
for(int i=1;i<=70;i++){
int mid=(l+r)>>1;
if(check(mid)) r=mid;
else l=mid;
}
cout<<r<<endl;
return 0;
}
D. Good Triple
题意:
对于给定的长度为 n n n的 01 01 01数组,计算有多少个区间 [ l , r ] [l,r] [l,r]使得 [ l , r ] [l,r] [l,r]内存在三个数 a i , a i + k , a i + 2 k a_i,a_{i+k},a_{i+2k} ai,ai+k,ai+2k并且 a i = a i + k = a i + 2 k a_i=a_{i+k}=a_{i+2k} ai=ai+k=ai+2k。
思路:
我们可以发现对于单纯的一个
01
01
01字符串来讲,最大长度不会超过15就会出现满足题目要求的情况。
因此,我们可以对于每个
l
l
l,寻找距离它最近的满足条件的
r
r
r。让答案每次加上
n
−
r
n-r
n−r即可,复杂度
O
(
15
∗
15
∗
n
)
O(15*15*n)
O(15∗15∗n)。
#include<bits/stdc++.h>
using namespace std;
int main(){
string s;
cin>>s;int n=(int)s.length();
long long ans=0;
for(int l=0;l<n;l++){
int maxxr=999999999;
for(int j=l;j<=l+15;j++){
for(int k=1;k<=15;k++){
if(s[j]==s[j+k]&&s[j]==s[j+2*k]){
maxxr=min(maxxr,j+2*k);
}
}
}
if(maxxr<n) ans+=(n-maxxr);
}
cout<<ans<<endl;
return 0;
}