第三道签到题没做出来,卡在读错题意和一个简单的逻辑bug,哭死
A题:
答案= |a-b|+x >n-1 ? n-1 : |a-b|+x
刚开始我竟想到取模,wsl。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
int n,x,a,b;
while(t--){
scanf("%d%d%d%d",&n,&x,&a,&b);
if(abs(a-b)==n-1){
printf("%d\n",n-1);
continue;
}
int ans=(abs(a-b)+x);
ans=ans>n-1?n-1:ans;
printf("%d\n",ans);
}
return 0;
}
B题:
直接特判,2和3比较特殊,2/2*3=3,(3-1)/2*3=3。
x>=y肯定可以,x只要不断减1 。
x<y,特判1,2,3,其余都是可以的,其他数字都可以经过 除2乘3不断 递增。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--){
int x,y;
scanf("%d%d",&x,&y);
if(y<=x){
puts("YES");
}
else {
if(x==1 || x==3){
puts("NO");
continue;
}
else if(x==2 && y>3){
puts("NO");
continue;
}
puts("YES");
}
}
return 0;
}
C题:
做法类似双指针,突然发现用数组存起来没啥用,直接双指针就ok了,然后不断更新最小值。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int pos[maxn][2];
bool cmp(int a,int b){
return a>b;
}
int main()
{
//freopen("input.txt","r",stdin);
int t;
scanf("%d",&t);
int n,x;
while(t--){
int pos_max=0;
memset(pos,0,sizeof(pos));
int ans=INT_MAX;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&x);
if(pos[x][0]==0){
pos[x][0]=i;
}
else if(pos[x][1]==0){
pos[x][1]=i;
ans=min(ans,pos[x][1]-pos[x][0]+1);
}
else{
pos[x][0]=pos[x][1];
pos[x][1]=i;
/* !!!应该不断更新,你记录的是最近两个数字的前后位置
if(pos[x][1]-pos[x][0]+1>i-pos[x][1]+1){
pos[x][0]=pos[x][1];
pos[x][1]=i;
}*/
ans=min(ans,pos[x][1]-pos[x][0]+1);
}
}
if(ans==INT_MAX)ans=-1;
printf("%d\n",ans);
}
return 0;
}
后续题目待做。。。