AtCoder Beginner Contest 417 (A-E题解)

比赛链接

总体总结

A,B题纯模拟

C题 公式一步转换

D题 五题里面最难的,dp预处理+二分

E题 排序+BFS

题解

A题 A Substring

复制代码
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long ll;
int t,n;
int a,b;
string s;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>a>>b;
    cin>>s;
    for(int i=a;i<n-b;i++)
    {
        cout<<s[i];
    }
    cout<<endl;

    return 0;
}

B题 Search and Delete

复制代码
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+10;
typedef long long ll;
int t,n,m;
int a[N];
int b[N];

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
        cin>>n>>m;
        for(int i=0;i<n;i++)cin>>a[i];
        for(int i=0;i<m;i++)cin>>b[i];
        sort(b,b+m);
        int cnt=0;
        for(int i=0;i<n;i++)
        {
            if(a[i]==b[cnt])a[i]=0,cnt++;
            else 
            {
                while(cnt<m&&a[i]>b[cnt])cnt++;
                if(cnt<m&&a[i]==b[cnt])a[i]=0,cnt++;
            }
            if(cnt==m)break;
        }
        for(int i=0;i<n;i++)
        {
            if(a[i]!=0)cout<<a[i]<<' ';
        }
    
    return 0;
}

C题 Distance Indicators

\j-i = A_i+A_j $$$$ j-A_j = i+A_i \\

复制代码
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef long long ll;
int t,n;
int a[N];
int cnt[2*N];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n;
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<=n;i++)
    {
        int x = i - a[i];
        if(x>=1&&cnt[x])ans+=cnt[x];
        cnt[i+a[i]]++;
    }
    cout<<ans<<endl;

    return 0;
}

D题 Takahashi's Expectation

首先dp预处理,dpij表示在第i个礼品时候的心情为j时,最后的心情是多少

然后用lower_bound(),求出什么时候mood小于前缀和presum,然后根据求出的位置,进行计算,如果求出,位置在结尾之后,说明一开始的心情过高,最后答案就是mood-presumn

复制代码
#include <bits/stdc++.h>
using namespace std;
const int N=1e4+10;
typedef long long ll;
int t,n;
int p[N],a[N],b[N];
int presum[N];
int dp[N][1001];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>p[i]>>a[i]>>b[i];
        presum[i]=presum[i-1]+b[i];
    }

    for(int i=0;i<=1000;i++)dp[n+1][i]=i;
    for(int i=n;i>=1;i--)
    {
        for(int j=0;j<=1000;j++)
        {
            if(j>p[i])
            {
                dp[i][j]=dp[i+1][max(0,j-b[i])];
            }
            else
            {
                dp[i][j]=dp[i+1][j+a[i]];
            }
        }
    }


    int q;
    cin>>q;
    while(q--)
    {
        int x;
        cin>>x;
        int mid = lower_bound(presum+1,presum+n+1,x-500)-presum;
        if(mid==n+1)
        {
            cout<<x-presum[n]<<endl;
        }
        else
        {
            cout<<dp[mid][x-presum[mid-1]]<<endl;
        }
    }


    return 0;
}

E题 A Path in A Dictionary

每次先把所有节点的边进行从小到大排序,然后bfs遍历每一个点,时间复杂度为O(n),求出字典序最小的路径

复制代码
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long ll;
int t,n;
int m,x,y;
bool flag = false;
bool vis[1001];
vector<ll>res;
vector<ll>graph[1001];
void dfs(int cur)
{
    if(flag)return;
    if(cur==y)
    {
        for(int i=0;i<res.size();i++)cout<<res[i]<<' ';
        cout<<endl;
        flag = true;
        return ;
    }

    for(auto it:graph[cur])
    {
        if(vis[it])continue;
        res.push_back(it);
        vis[it]=true;
        dfs(it);
        res.pop_back();
    }


    
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>t;
    while(t--)
    {
        flag =false;
        memset(vis,false,sizeof(vis));
        cin>>n>>m>>x>>y;
        for(int i=1;i<=1000;i++)graph[i].clear();
        for(int i=1;i<=m;i++)
        {
            int f,t;
            cin>>f>>t;
            graph[f].push_back(t);
            graph[t].push_back(f);
        }
        for(int i=1;i<=n;i++)sort(graph[i].begin(),graph[i].end());
        vis[x]=true;
        res.push_back(x);
        dfs(x);
        res.clear();

    }


    return 0;
}
相关推荐
Logic10117 小时前
C语言/数据结构动态规划题解:Kadane算法求最大子数组和——O(n)时间O(1)空间
c语言·数据结构·动态规划·贪心·时间复杂度·算法题·最大子数组和
梦帮科技1 天前
AI 音乐产品的发布工程:验证门、数据发布、回滚与生产运维纪律
数据结构·数据库·架构·node.js·音视频·动态规划·推荐算法
语戚1 天前
力扣 1621. 大小为K的不重叠线段的数目:动态规划(Java 实现)
java·算法·leetcode·动态规划·力扣·dp
青山木1 天前
Hot 100 --- 最长有效括号
java·数据结构·算法·leetcode·动态规划
这料鬼有毒1 天前
二刷hot100-1143.最长公共子序列
算法·leetcode·动态规划
Tisfy2 天前
LeetCode 1477.找两个和为目标值且不重叠的子数组:滑动窗口 + 记录前值(动态规划)
动态规划·题解·dp·滑动窗口
ynchyong3 天前
动态规划解题思路:入门篇
动态规划
Tisfy4 天前
LeetCode 2472.不重叠回文子字符串的最大数目:动态规划(贪心)
动态规划·字符串·题解·贪心·dp·回文字符串
青山木5 天前
Hot 100 --- 最长递增子序列
java·数据结构·算法·leetcode·动态规划
Logic1015 天前
C语言/数据动态规划题解:翻转一次子数组后的最大子数组和——四状态DP(O(n)时间O(1)空间)
c语言·数据结构·动态规划·时间复杂度·算法题·状态机dp·最大子数组和