暑期算法训练10 - 蓝桥杯算法双周赛第16场题解(A~F)

蓝桥杯的双周赛难度还是比较低的,但是用来练手还是相当不错的,先贴个比赛链接——https://www.lanqiao.cn/oj-contest/newbie-16/,接下来分享我的代码—— 

目录

A题

题面

思路分析

代码实现

B题

题面

思路分析

代码实现

C题

题面

思路分析

代码实现

D题

题面

思路分析

代码实现

E题

题面

思路分析

代码实现

F题

题面

思路分析

代码实现


A题

题面

思路分析

直接输出,ceil向上取整一下

代码实现

#include <iostream>
#include <cstring>
using namespace std;
int main()
{
    cout << ceil(365 * 1.0/7) << endl;
    return 0;
}

B题

题面

思路分析

简单按题意字符串模拟即可

代码实现

#include <iostream>
#include <cstring>
using namespace std;
int main()
{
  int n;
  cin >> n;
  string s;
  cin >> s;
  for(int i = 0; i <  s.size(); i++)
  {
     int x;
     cin >> x;
     cout << s[x - 1];
  }
  return 0;
}

C题

题面

思路分析

开两个哈希表map,然后遍历两个字符串把字母存进哈希表内,再从'a'枚举到‘z’,更新两个哈希表中相同元素的差值(绝对值),如果大于2则表示S和T即使分别删除一个字母后仍存在不同的元素,则不能实现目标,输出NO,否则输出YES

代码实现

#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#define int long long
#define x first
#define y second
using namespace std;
const int N = 1e5 + 10;

void solve()
{
     map<char,int> mp1;
     map<char,int> mp2;
     int cnt1[N];
     int cnt2[N];
     string a,b;
     cin >> a >> b;
     if((a == b) || (a.size() == 1 && b.size() == 1))
     {
        cout << "YES" << endl;
        return ;
     }
     for(int i = 0; i < a.size(); i++)
     {
          mp1[a[i]] ++ ;
          mp2[b[i]] ++;
     }
     int ans = 0;
     for(int i = 'a'; i <= 'z'; i++)
     {
        if(mp1[i] != mp2[i]) ans += abs(mp1[i] - mp2[i]);
     }
     if(ans > 2) cout << "NO" << endl;
     else cout << "YES" << endl;
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr),cout.tie(nullptr);
    int t ;
    cin >> t;
    while(t -- )
  {
    solve();
  }
    return 0;
}

D题

题面

思路分析

因为输入的坐标不一定就是有序的,所以必须要先进行递增排序,但是每个坐标都绑定了一个安全距离,所以要用pair来排序,之后模拟题意即可

代码实现

#include<iostream>
#include<algorithm>
#define int long long
#define x first
#define y second
using namespace std;
const int N = 1e5 + 10;
int a[N];
int b[N];
typedef pair<int,int> PII;
PII p[N];
void solve()
{
    int ans = 0;
    int n;
    cin >> n;
    for(int i = 1; i <= n; i++)  cin >> a[i];
    for(int i = 1; i <= n; i++)  cin >> b[i];  
    for(int i = 1; i <= n; i++)  p[i] = {a[i],b[i]};
    sort(p + 1 , p + n + 1);
    //for(int i = 1; i <= n; i++) cout << p[i].x << " " << p[i].y << endl;
    for(int i = 1; i <= n; i++)
    {
         if(i == 1) 
         {
             if(p[i].x + p[i].y < p[2].x)  ans++;
         }
         else if(i == n)
         {
             if(p[i].x - p[i].y > p[i - 1].x) ans++;
         }
         else  
         {
             if(p[i].x + p[i].y < p[i + 1].x && p[i].x - p[i].y > p[i - 1].x)  ans++;
         }
    }
    cout << ans << endl;
}
    
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr),cout.tie(nullptr);
    int t  = 1;
    while(t -- ) solve();
    return 0; 
}

E题

题面

思路分析

首先本题是一个树结构,两两顶点相连,所以我们首先定义一个动态vector二维数组读入树结构,然后就是考察我们的思维了,题目中说要找“朋友的朋友”,于是我们知道“朋友的度”就是我们“朋友的朋友” ,但是“朋友的度”同样都包含“我们”,所以邻居的度总和要减掉自身的度总和才为答案,很不错的一题哈哈,看看代码——(当然也可以dfs去做,但我觉得本题dfs就有点绕了,还是直接按思维模拟好理解一点,但不管怎样都能ac)

代码实现

#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <vector>
#define int long long
#define x first
#define y second
using namespace std;
const int N = 2e5 + 10;
int n;
vector<vector<int>> G(N,vector<int>());//开二维数组
//vector<int> G[N];
int ans[N];
/* void dfs(int u,int fa)
{
    for(auto v:G[u])
    {
        if(v == fa)
        {
            ans[v] += G[u].size() - 1;
            continue;
        }
        dfs(v,u);
        ans[v] += G[u].size() - 1;
    }
} */
void solve()
{
    cin >> n;
    for(int i = 1; i < n; i++) 
    {
        int u,v;
        cin >> u >> v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    /* dfs(1,0);
    for(int i = 1; i <= n; i++) 
    cout << ans[i] << " ";
    cout << endl; */
    for(int i = 1; i <= n; i++)
    {
        int t = 0;
        for(int v : G[i]) t = t + G[v].size(); //邻居的度(但是每个邻居的度都包含自己)
        cout << t - G[i].size() << " ";  //(所以和减去自己的度)
    }
   /*  for(int i = 1; i <= n; i++)
    {
        int t = 0;
        for(int v : G[i]) t += G[v].size() - 1; 
        cout << t  << " ";  
    } */
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr),cout.tie(nullptr);
    int t = 1;
    /* cin >> t; */
    while(t -- )  solve();
    return 0;
}

F题

题面

思路分析

本题考察动态规划,dp[i]表示亲密值不超过i的所有可能种数
分为两种情况:

1.最后一次约会刚好到达i,那么最后一次约会前的亲密值必须是小于等于(i - k),这种情况可能种数为dp[i - k]。
2.
最后一次约会后还是小于i,这种情况可能种数为dp[i - 1]
故状态转移方程为
dp[i] = dp[i - k] + dp[i - 1],需注意取模运算

代码实现

#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#define int long long
#define x first
#define y second
using namespace std;
const int N = 1e5 + 10;
const int mod = 1e9 + 7;
int dp[N];
//dp[i]表示亲密值不超过i的所有可能种数
//分为两种情况 1.最后一次约会刚好到达i,那么最后一次约会前的亲密值必须是小于等于(i - k),这种情况可能种数为dp[i - k]
//2.最后一次约会后还是小于i,这种情况可能种数为dp[i - 1]
//故状态转移方程为dp[i] = dp[i - k] + dp[i - 1]
void solve()
{
    int n,k;
    cin >> n >> k;
    for(int i = 0; i < k; i++) dp[i] = 1;
    for(int i = k; i <= n; i++)
    {
        dp[i] = (dp[i - k] + dp[i - 1]) % mod;
    }
    cout << dp[n] % mod << endl;
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr),cout.tie(nullptr);
    int t = 1;
    /* cin >> t; */
    while(t -- )
    solve();
    return 0;
}

一转眼2024年的暑假也快结束了,八月份在家在牛客,洛谷,acwing,cf以及atcoder等做了不少题,虽然可能下学期大三面临着考研或找工作压力不能再继续打线上赛,更新题解了,又或许也没太多机会能打线下的算法竞赛了,但是我对程序设计的热爱依旧在路上,这个暑假应该是学业生涯最后一个轻松的暑假了,希望未来越来越好!!!

猜你喜欢

转载自blog.csdn.net/weixin_73332175/article/details/141440339