A. Cancel the Trains
去重,重复才会相撞
B. Suffix Operations
后缀+1,后缀-1
操作前可以改变一个值。
求最少操作数使得数列相同。
很明显是差分。差分数组和就是操作数。
当我们改变一个数列中间的值时,最优肯定是改成与前面相同的情况。(与后面相同也行,差分数组是一样的。
当前情况,ci改变为0,ci+1改变为a+1 - a-1
特殊的,改变a1,那么只有c2改变为0
特殊的,改变an,那么只有cn改变为0
取最优情况记录。
最后差分求和。
ll a[N],n,m,x,c[N]; int main(){ int t;cin>>t; while(t--){ scanf("%lld",&n); for(int i=1;i<=n;++i){ scanf("%lld",&a[i]); } ll ans=0,re=-1,pos=0,now; for(int i=1;i<=n;++i) c[i]=a[i]-a[i-1]; for(int i=2;i<n;++i){ ll pre=fabs(c[i])+fabs(c[i+1]); ll now=fabs(a[i+1]-a[i-1]); if(pre-now>re){ re=pre-now;pos=i; } } ll now1=fabs(c[2]); ll now2=fabs(c[n]); if(re>=now1&&re>=now2){ c[pos]=0;c[pos+1]=a[pos+1]-a[pos-1]; } else if(now1>=re&&now1>=now2){ c[2]=0; } else if(now2>=re&&now2>=now1){ c[n]=0; } for(int i=2;i<=n;++i) ans=ans+fabs(c[i]); cout<<ans<<endl; } return 0; }
C. Triangles
矩阵中找三个相同值的点,凑一个三角形,要求面积最大。三角形有一边平行于外边。
值范围为0-9,都要输出
存入的时候,把每个值能到达的左上,右上,左下,右下都储存下来。
当前值点数小于2的没有三角
由于我们能造一个点出来,所以
跑一遍矩阵,找当前点值能在四个方向上凑出的最大值。(选最优的底和最优的高
取一个点,找一个点,造一个点构成我们的三角形
#include<bits/stdc++.h> #define ll long long #define inf 1e17 using namespace std; const long long N =3e3+7; ll a[N][N],n; ll minx[20],miny[20],maxx[20],maxy[20],ans[32],c[20]; int main(){ int t;cin>>t; while(t--){ scanf("%lld",&n); for(ll i=0;i<10;i++) minx[i]=miny[i]=n+1,maxx[i]=maxy[i]=0,ans[i]=0,c[i]=0; for(ll i=1,xx;i<=n;i++) for(ll j=1;j<=n;j++){ scanf("%1d",&a[i][j]); xx=a[i][j];c[xx]++; minx[xx]=min(minx[xx],i); miny[xx]=min(miny[xx],j); maxx[xx]=max(maxx[xx],i); maxy[xx]=max(maxy[xx],j); } for(ll i=1;i<=n;i++) for(ll j=1;j<=n;j++){ ll xx=a[i][j]; if(c[xx]<2) continue; ll dx=max(maxx[xx]-i,i-minx[xx]); ll dy=max(maxy[xx]-j,j-miny[xx]); ans[xx]=max(ans[xx],dx*max(n-j,j-1)); ans[xx]=max(ans[xx],dy*max(n-i,i-1)); } for(int i=0;i<10;i++) cout<<ans[i]<<' ';puts(""); } return 0; }
-----------
希望下次打CF的时候,犯病少一点