8.30NOIP Day15模拟赛
T1
对于本来 \(i<j\) 的情况,我们将其记作 \(i>j\) 绝对值一定不优,所以就不用管他,直接处理
对于每一个 \(i\) 枚举在它每一个方向的点,取最大值
#include<bits/stdc++.h>
#define int long long
#define N 1000005
using namespace std;
int x[N][5],maxx[20];
signed main(){
int n,k;
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n;i++)for(int j=1;j<=k;j++)scanf("%lld",&x[i][j]);
for(int i=1;i<=n;i++){
for(int j=0;j<(1<<k);j++){
int now=0;
for(int l=1;l<=k;l++){
if(j&(1<<(l-1)))now+=x[i][l];
else now-=x[i][l];
}
maxx[j]=max(maxx[j],now);
}
}
int ans=0;
for(int i=1;i<=n;i++){
for(int j=0;j<(1<<k);j++){
int now=0;
for(int l=1;l<=k;l++){
if(j&(1<<(l-1)))now-=x[i][l];
else now+=x[i][l];
}
ans=max(ans,now+maxx[j]);
}
}
printf("%lld\n",ans);
return 0;
}
T2
根据给出的border,我们可以判断出哪些字母是相同的
然后就是跑一下,根据之前推出的给上类似kmp的优化就行了
#include<bits/stdc++.h>
#define N 1000005
using namespace std;
int x[N],fa[N],s[N],y[N];
int findd(int u){
if(fa[u]==u)return u;
return fa[u]=findd(fa[u]);
}
signed main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&x[i]);
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=n;i++)if(x[i])fa[i]=findd(x[i]);
for(int i=1;i<=n;i++)s[i]=findd(i);
y[1]=n;
int now=n,p=0;
for(int i=2;i<=n;i++){
if(y[p]+p-1>=i)now=min(y[i-p+1],y[p]+p-i);
else now=0;
now=min(now,n-i+1);
while(now<=n&&s[i+now]==s[now+1])now++;
y[i]=now;
if(y[i]+i-1>y[p]+p-1)p=i;
}
for(int i=1;i<=n;i++)printf("%d ",y[i]);
return 0;
}
T3
就是把正三角形压成上三角形,再移位1格,然后会得到一个状似最短路三角形不等式的关系式,上去跑floyd即可
#include<bits/stdc++.h>
#define int long long
#define N 1005
using namespace std;
int f[N][N];
signed main(){
int n,m,q;
scanf("%lld%lld%lld",&n,&m,&q);
n++;
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)f[i][j]=1e18;
for(int i=1;i<=n;i++)f[i][i]=0;
for(int i=1;i<=m;i++){
int u,v,w;
scanf("%lld%lld%lld",&u,&v,&w);
f[u-v+1][u+1]=f[u+1][u-v+1]=w;
}
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)for(int k=1;k<=n;k++)f[j][k]=min(f[j][k],f[j][i]+f[i][k]);
while(q--){
int xa,ya,xb,yb;
scanf("%lld%lld%lld%lld",&xa,&ya,&xb,&yb);
printf("%lld\n",f[xa-ya+1][xa+1]+f[xb-yb+1][xb+1]);
}
return 0;
}

浙公网安备 33010602011771号