上大学以后第一次CF居然打的这么好……新号StudyingMother打的,rank35,rating=837。
手速不行思维慢,还天天WA,我哭辽……
A
签到,输出字符串长度
B
发现尽量往右边跳最优,-1可视为-(k+1)(第k次跳跃),然后发现那一次如果恰好能跳到x或者跳到>=x+2,则这样跳的次数就是答案,如果跳到x+1则为跳的次数+1
#include<bits/stdc++.h> using namespace std; const int N=2e6; int n; int main() { int T;scanf("%d",&T); while(T--) { scanf("%d",&n); int sum=0; for(int i=1;;i++) { sum+=i; if(sum-n>1||sum-n==0){printf("%d ",i);break;} } } }
C
签到,发现尽量不接球会好一些,等到对方没有体力再回击即可,所以答案是x-1 y
D
可以把序列直接切割成若干极长单调子段,然后从左到右每一段尽可能多交换,特判-1即可,但细节有点多容易WA
#include<bits/stdc++.h> using namespace std; int T,n,x,a[555]; int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&n,&x); int ans=0; for(int i=1;i<=n;i++)scanf("%d",&a[i]); int pre=1; for(int i=1;i<n;i++) if(a[i]>a[i+1]) { if(pre==i&&x>a[i+1]||pre!=i&&max(x,a[i-1])>a[i+1]){ans=-1;break;} for(int j=pre;j<=i;j++)if(a[j]>x)ans++,swap(a[j],x); pre=i+1; } printf("%d ",ans); } }
E
枚举哪两个点在一条横线/竖线,移动的最小距离可以为该两点的横/纵坐标相减的绝对值,容易算出其最小和最大的边长,发现如果二者可以相等则+0,反之再+2*(大者的最小值-小者的最大值),代码很麻烦。一个优化技巧:O(6)枚举即可,钦定第一个点在第一条横线&竖线上,枚举另一个与第一个点在一条横线&竖线的点(二者不相同)即可。
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll x[4],y[4]; int main() { int T;cin>>T; while(T--) { for(int i=0;i<4;i++)cin>>x[i]>>y[i]; ll ans=1e18; for(int i=1;i<4;i++) for(int j=1;j<4;j++) if(i!=j) { ll lx1,ux1,lx2,ux2,ly1,uy1,ly2,uy2,mnx,mxx,mny,mxy; ll sum=abs(x[0]-x[i])+abs(y[0]-y[j]); lx1=min(x[0],x[i]),ux1=max(x[0],x[i]); ly1=min(y[0],y[j]),uy1=max(y[0],y[j]); if(i==1)sum+=abs(x[2]-x[3]),lx2=min(x[2],x[3]),ux2=max(x[2],x[3]); else if(i==2)sum+=abs(x[1]-x[3]),lx2=min(x[1],x[3]),ux2=max(x[1],x[3]); else sum+=abs(x[1]-x[2]),lx2=min(x[1],x[2]),ux2=max(x[1],x[2]); if(j==1)sum+=abs(y[2]-y[3]),ly2=min(y[2],y[3]),uy2=max(y[2],y[3]); else if(j==2)sum+=abs(y[1]-y[3]),ly2=min(y[1],y[3]),uy2=max(y[1],y[3]); else sum+=abs(y[1]-y[2]),ly2=min(y[1],y[2]),uy2=max(y[1],y[2]); if(lx1>lx2)swap(lx1,lx2),swap(ux1,ux2); if(ly1>ly2)swap(ly1,ly2),swap(uy1,uy2); if(lx2<=ux1)mnx=0;else mnx=lx2-ux1; mxx=max(ux2-lx1,ux1-lx2); if(ly2<=uy1)mny=0;else mny=ly2-uy1; mxy=max(uy2-ly1,uy1-ly2); if(mnx>mny)swap(mnx,mny),swap(mxx,mxy); if(mxx<mny)sum+=2*(mny-mxx); ans=min(ans,sum); } printf("%lld ",ans); } }