Title

ABC335 A~E 题解

A

题目大意

输入一个字符串,把这个字符串的最后一位改成 4 后输出这个字符串。

解题思路

直接模拟即可

AC 代码

#include<iostream>
#include<math.h>
#include<time.h>
#include<stdio.h>
#include<algorithm>
#define ll long long
inline void work(){
    std::string s;
    std::cin>>s;
    s[s.length()-1]='4';
    std::cout<<s;
}signed main(){
    srand(114514);
    srand(rand());
    srand(time(0));
    
    work();system("pause");
}

B

题目大意

输入一个 \(n\),求出所有满足 \(x+y+z\le n\) 的三元组 \((x,y,z)\),按字典序升序输出。

解题思路

直接从小到大枚举 \(x\)\(y\)\(z\) 即可,判断是否满足 \(x+y+z\le n\),满足的话直接输出即可。注意枚举的时候从 \(0\) 开始。

AC 代码

#include<iostream>
#include<math.h>
#include<time.h>
#include<stdio.h>
#include<algorithm>
#define ll long long
int n;
inline void work(){
    scanf("%d",&n);
    for(register int i=0;i<=n;++i)
    for(register int j=0;j<=n;++j)
    for(register int k=0;k<=n;++k){
        if(i+j+k>n) continue;
        printf("%d %d %d\n",i,j,k);
    }
}signed main(){
    srand(114514);
    srand(rand());
    srand(time(0));
    
    work();system("pause");
}

C

题目大意

一个贪吃蛇,共 \(n\) 部分,初始时第 \(i\) 部分位于位置 \((i,0)\),共有 \(q\) 次操作,分为以下两种操作:

  • 1 CC 为移动方向,包括 LRUD,分别表示向左、向右、向上、向下移动;
  • 2 P:查询位置第 \(P\) 个部分的位置。

解题思路

直接模拟会 TLE。观察发现当前部分所在位置一定是第 \(1\) 部分之前某个时刻所在的位置或初始时某个部分所在的位置,那么直接记录第 \(1\) 部分每次移动后的位置即可。设当前经过了 \(t\)\(1\) 操作,当前部分所在位置一定是 \(1\) 位置在 \(t-(P-1)\)\(1\) 操作后所在的位置,如果 \(t-(P-1)<0\),那么当前部分位于第 \(P-t\) 个部分初始时所在的位置。

AC 代码

#include<iostream>
#include<math.h>
#include<time.h>
#include<stdio.h>
#include<algorithm>
#define ll long long

#define N 200005
int n,q,ce;
std::pair<int,int>pos[N];
inline void Update(){
    char c;
    std::cin>>c;
    int x=pos[ce].first;
    int y=pos[ce].second;
    ce++;
    if(c=='R') pos[ce]={x+1,y};
    else if(c=='L') pos[ce]={x-1,y};
    else if(c=='U') pos[ce]={x,y+1};
    else pos[ce]={x,y-1};
}
inline void Query(){
    int x;scanf("%d",&x);
    int delta=x-1;
    if(delta>=ce){
        delta-=ce;++delta;
        printf("%d 0\n",delta,0);
        return;
    }
    int X=pos[ce-delta].first;
    int Y=pos[ce-delta].second;
    printf("%d %d\n",X,Y);
}
inline void work(){
    scanf("%d%d",&n,&q);
    pos[0]={1,0};
    int opt;
    while(q--){
        scanf("%d",&opt);
        if(opt==1) Update();
        else Query();
    }
}signed main(){
    srand(114514);
    srand(rand());
    srand(time(0));
    
    work();system("pause");
}

D

题目大意

一个 \(n\times n\) 的矩阵,在 \((\frac{n+1}{2},\frac{n+1}{2})\) 处填入字符 T,其余位置需要填入整数 \(1\sim n\times n-1\),同时需要满足填入整数 \(x\) 的位置和填入整数 \(x-1\) 的位置相邻。

解题思路

因为在矩阵中心填入 T,那么剩余位置蛇形填入即可。

AC 代码

#include<iostream>
#include<math.h>
#include<time.h>
#include<stdio.h>
#include<algorithm>
#define ll long long
#define N 50
int n,map[N][N];
int f[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
inline void work(){
    scanf("%d",&n);
    map[(n+1)/2][(n+1)/2]=n*n;
    int now=1,loc=0,x=1,y=1;
    while(now<n*n){
        map[x][y]=now;
        int fx=x+f[loc][0];
        int fy=y+f[loc][1];
        if(fx<1||fy<1) loc=(loc+1)%4;
        else if(fx>n||fy>n) loc=(loc+1)%4;
        else if(map[fx][fy]) loc=(loc+1)%4;
        fx=x+f[loc][0],fy=y+f[loc][1];
        x=fx,y=fy;++now;
    }
    for(register int i=1;i<=n;++i){
        for(register int j=1;j<=n;++j){
            if(map[i][j]==n*n)
                putchar('T'),putchar(' ');
            else printf("%d ",map[i][j]);
        }putchar('\n');
    }
}signed main(){
    srand(114514);
    srand(rand());
    srand(time(0));
    
    work();system("pause");
}

E

题目大意

已知一个 \(n\) 个点 \(m\) 条边的无向图,第 \(i\) 个点的点权为 \(v_i\),如果一条简单路径满足经过的点的点权单调不下降,那么这条路径的值为路径上点权不同的点的数量,否则为 \(0\),输出值最大的路径的值。

解题思路

把点权从小到大排序,对于每个点,枚举它的连边中点权比他小的点,同时更新从这个点路径的值,如果点权和它相等,那么取最大值。然后暴力向前更新点权和它一样的点的路径的值,最后输出即可。

AC 代码

#include<iostream>
#include<math.h>
#include<time.h>
#include<stdio.h>
#include<algorithm>
#include <set>
#include <vector>
#include <string.h>
#define ll long long
#define N 200005
#define inf 2e9+7
struct Edge{
    int u,w;
}a[N];int b[N];
std::vector<int> edge[N];
std::set<int> s;
int n,m,dp[N],num;
inline bool cmp(Edge A,Edge B){
    if(A.w!=B.w)
        return A.w<B.w;
    return A.u<B.u;
}
int vis[N];
inline void dfs(int u){
    s.insert(u);
    if(dp[u]>num)
        num=dp[u];
    vis[u]=1;
    for(auto v:edge[u]){
        if(vis[v]) continue;
        if(b[v]!=b[u])
            continue;
        dfs(v);
    }
}
inline void GetAns(){
    for(register int i=1;i<=n;++i){
        int u=a[i].u,w=a[i].w;
        for(auto v:edge[u]){
            if(w>b[v]) 
                dp[u]=std::max(dp[u],dp[v]+1);
            else if(w==b[v]) 
                dp[u]=std::max(dp[u],dp[v]);
        }if(w==a[i+1].w&&i!=n) continue;
        int j=i;while(a[j].w==w&&j>=1){
            u=a[j].u;
            if(!vis[u]){ s.clear();
                num=-inf;dfs(u);
                for(auto v:s)
                    dp[v]=num;
            }--j;
        }
    }
}
inline void work(){
    scanf("%d%d",&n,&m);int u,v;
    for(register int i=1;i<=n;++i){
        scanf("%d",&a[i].w);
        a[i].u=i;b[i]=a[i].w;
    }std::sort(a+1,a+n+1,cmp);
    for(register int i=1;i<=m;++i){
        scanf("%d%d",&u,&v);
        edge[u].push_back(v);
        edge[v].push_back(u);
    }memset(dp,-0x3f,sizeof(dp));
    dp[1]=1;GetAns();
    printf("%d",dp[n]<0?0:dp[n]);
}signed main(){
    srand(114514);
    srand(rand());
    srand(time(0));
    
    work();system("pause");
}
posted @ 2024-02-07 10:07  UncleSam_Died  阅读(40)  评论(1)    收藏  举报