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;
}
posted @ 2025-08-30 10:25  Igunareo  阅读(14)  评论(0)    收藏  举报