CF505

CF505A

注意到 \(|s|<=10\),那么暴力枚举每个字母和插入位置即可。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline 
#define gc getchar
#define pc putchar
const int N=5e4+5;
const int M=2e7+5;
const int inf=0x7fffffff;
const int mod=1e6+3;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,m;
string s,t,k;
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>s;
    for(int i=0;i<=s.size();i++){
        for(int j=1;j<=26;j++){
            t=s;k=(char)('a'+j-1);
            t.insert(i,k);int flag=1;
            for(int l=0,r=t.size()-1;l<r;l++,r--)flag&=t[l]==t[r];
            if(flag){
                cout<<t<<endl;
                return 0;
            }
        }
    }
    puts("NA");
    return 0;
}

CF505B

\(n,m,q\leq 100\) 那么 \(O(n^3m)\) 暴力 floyd 即可

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline 
#define gc getchar
#define pc putchar
const int N=1e2+5;
const int M=2e7+5;
const int inf=0x7fffffff;
const int mod=1e6+3;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,m,dis[N][N][N];
signed main(){
    n=read();m=read();
    for(int i=1;i<=m;i++){
        int u=read(),v=read(),c=read();
        dis[u][v][c]=dis[v][u][c]=1;
    }
    for(int c=1;c<=m;c++){
        for(int k=1;k<=n;k++){
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    dis[i][j][c]|=dis[i][k][c]&dis[k][j][c];
                }
            }
        }
    }
    int q=read();
    while(q--){
        int u=read(),v=read(),ans=0;
        for(int i=1;i<=m;i++)ans+=dis[u][v][i];
        writel(ans);
    }
    return 0;
}

CF505C

发现贪心不可行,那么考虑dp。
一个显然的状态:设 \(f_{i,j}\) 表示到 \(i\) 位置,上一次走 \(j\) 步的最大答案 转移显然
然鹅 \(n,m\leq 30000\) 空间、时间都炸了
发现每次步数只会+1或-1 发现步数最大只会变400次
那么改下状态:设 \(f_{i,j}\) 表示到 \(i\) 位置,上一次教开始的 \(d\) 变化了 \(j-M\) 的最大答案
(M=400 整体右移 防止出现负数)

复杂度 \(O(800n)\)

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline 
#define gc getchar
#define pc putchar
const int N=3e4+5;
const int M=4e2+5;
const int inf=0x7fffffff;
const int mod=1e6+3;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,d,num[N],f[N][(M<<1)+5],p[N],ans;
signed main(){
    n=read(),d=read();
    for(int i=1;i<=n;i++){
        p[i]=read();
        num[p[i]]++;
    }
    memset(f,-1,sizeof f);
    f[d][M]=num[0]+num[d];
    for(int i=d;i<=p[n];i++){
        for(int j=-M;j<=M;j++){
            if(!~f[i][j+M])continue;
            for(int z=-1;z<=1;z++){
                int len=j+d+z;
                if(len<1||i+len>p[n]||j+z+M<0||j+z+M>(M<<1))continue;
                f[i+len][j+M+z]=max(f[i+len][j+M+z],f[i][j+M]+num[i+len]);
            }
            ans=max(ans,f[i][j+M]);
        }
    }
    writel(ans);
    return 0;
}

CF505D

发现如下性质:

  • 当该联通块为DAG时 一定可以用一条链连起来 且满足题意
  • 当联通块中有环时 就把所有点串成环 两点之间必然可达

两种情况答案分别为 \(cnt-1\)\(cnt\)
(\(cnt\) 为联通块大小)

可以通过拓扑排序判环 存在一个点入度总大于0则有环

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline 
#define gc getchar
#define pc putchar
const int N=1e5+5;
const int M=4e2+5;
const int inf=0x7fffffff;
const int mod=1e6+3;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,m,fa[N],in[N],ans,q[N],h,t=1,inq[N],res[N];
int head[N],nxt[N],to[N],cnt;
inl void add(int u,int v){
    nxt[++cnt]=head[u];
    to[cnt]=v;
    head[u]=cnt;
}
inl int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
signed main(){
    n=ans=read(),m=read();
    for(int i=1;i<=n;i++)fa[i]=i;
    for(int i=1;i<=m;i++){
        int u=read(),v=read();
        add(u,v);
        in[v]++;
        int fu=find(u),fv=find(v);
        if(fu==fv)continue;
        fa[fu]=fv;
    }
    for(int i=1;i<=n;i++){
        if(!in[i])q[++h]=i,inq[i]=1;
    }
    while(h>=t){
        int x=q[t++];
        for(int i=head[x];i;i=nxt[i]){
            int y=to[i];
            if(!--in[y])q[++h]=y,inq[y]=1;
        }
    }
    for(int i=1;i<=n;i++){
        if(!inq[i])res[find(i)]=1;
    }
    for(int i=1;i<=n;i++){
        if(i^find(i))continue;
        ans-=!res[i];
    }
    writel(ans);
    return 0;
}
posted @ 2023-11-24 10:44  xiang_xiang  阅读(4)  评论(0编辑  收藏  举报