2022蓝桥杯C++B组国赛真题题解(三)

简介: 2022蓝桥杯C++B组国赛真题题解

H:机房


问题描述

这天, 小明在机房学习。


他发现机房里一共有 n 台电脑, 编号为 1 到 n, 电脑和电脑之间有网线连 接, 一共有 n−1 根网线将 n 台电脑连接起来使得任意两台电脑都直接或者间 接地相连。


小明发现每台电脑转发、发送或者接受信息需要的时间取决于这台电脑和 多少台电脑直接相连, 而信息在网线中的传播时间可以忽略。比如如果某台电脑 用网线直接连接了另外 d 台电脑, 那么任何经过这台电脑的信息都会延迟 d 单 位时间 (发送方和接收方也会产生这样的延迟, 当然如果发送方和接收方都是 同一台电脑就只会产生一次延迟)。


小明一共产生了 m 个疑问: 如果电脑 ui 向电脑 vi 发送信息, 那么信息从 ui 传到 vi 的最短时间是多少?


输入格式

输入共 n+m 行, 第一行为两个正整数 n,m 。


后面 n−1 行, 每行两个正整数 x,y 表示编号为 x 和 y 的两台电脑用网线 直接相连。


后面 mm 行, 每行两个正整数 ui,vi 表示小明的第i 个疑问。


输出格式

输出共 m 行, 第 i 行一个正整数表示小明第 ii 个疑问的答案。


样例输入

4 3
1 2
1 3
2 4
2 3
3 4
3 3

样例输出

5
6
1

样例说明

这四台电脑各自的延迟分别为 2,2,1,1 。


对于第一个询问, 从 2 到 3 需要经过 2,1,3, 所以时间和为 2+2+1=5 。


对于第二个询问, 从 3 到 4 需要经过 3,1,2,4, 所以时间和为 1+2+2+1=6。


对于第三个询问, 从 3 到 3 只会产生一次延迟, 所以时间为 1 。


评测用例规模与约定

对于 30% 的数据, 保证n,m≤1000;


对于 100% 的数据, 保证n,m≤100000 。


运行限制

最大运行时间:1s

最大运行内存: 512M

小编这题只会偏偏分,AC需要LCA加DFS加树的前缀和。我们看看大佬的代码吧,大体就是建一个数,统计每个节点到根节点的延时,然后通过LCA寻找询问两个点的最近公共祖先,算出最小延时。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=100010;
unordered_map<int,vector<int>> gra;
int n,m;
//单个点的出度
int d[N];
//记录点i到根节点的延迟
int w[N];
//并查集数组
int q[N];
//记录答案
int res[N];
int st[N];
//存下查询
vector<PII> query[N];
//并查集查询
int find(int x){
  if(x!=q[x]) q[x]=find(q[x]);
  return q[x];
}
void dfs(int u,int fa)
{
  w[u]+=d[u];
  for(auto g:gra[u]){
    if(g==fa) continue;
    w[g]+=w[u];
    dfs(g,u);
  }
}
void tarjan(int u)
{
  st[u]=1;
  for(auto j:gra[u]){
    if(!st[j])
    {
      tarjan(j);
      q[j]=u;
    }
  }
  for(auto item: query[u]){
    int y=item.first,id=item.second;
    if(st[y]==2){
      int anc=find(y);
      res[id]=w[y]+w[u]-w[anc]*2+d[anc];
    }
  }
  st[u]=2;
}
int main() 
{
  cin>>n>>m;
  for(int i=0;i<n-1;++i){
    int a,b;
    scanf("%d%d",&a,&b);
    gra[a].push_back(b);
    gra[b].push_back(a);
    d[a]++,d[b]++;
  }
  for(int i=0;i<m;++i){
    int a,b;
    scanf("%d%d",&a,&b);
    if(a!=b){
      query[a].push_back({b,i});
      query[b].push_back({a,i});
    }else{
      res[i]=d[a];
    }
  }
  dfs(1,-1);
  for(int i=1;i<=n;++i) q[i]=i;
  tarjan(1);
  for(int i=0;i<m;++i) printf("%d\n",res[i]);
    return 0;
}

I:齿轮


问题描述

这天, 小明在组装齿轮。


他一共有 n 个齿轮, 第 i 个齿轮的半径为 ri, 他需要把这 n 个齿轮按一定 顺序从左到右组装起来, 这样最左边的齿轮转起来之后, 可以传递到最右边的 齿轮, 并且这些齿轮能够起到提升或者降低转速 (角速度) 的作用。

小明看着这些齿轮, 突然有 QQ 个疑问:能否按一定顺序组装这些齿轮使得 最右边的齿轮的转速是最左边的齿轮的 qi 倍?


输入格式

输入共 Q+2 行, 第一行为两个正整数 n,Q, 表示齿轮数量和询问数量。 第二行为 n 个正整数 r1,r2,…,rn, 表示每个齿轮的半径。


后面 Q 行, 每行一个正整数 qi 表示询问。


输出格式

Q 行, 对于每个询问, 如果存在至少一种组装方案满足条件, 输出 'YES', 否则输出 'NO '。


样例输入

5 3
4 2 3 3 1 
2 
4 
6

样例输出

YES
YES
NO  

样例说明

询问 1 方案之一 : 23341


询问 2 方案之一:42331


询问 3 没有方案


评测用例规模与约定

对于 15% 的数据, 保证 n,Q≤100;


对于 30% 的数据, 保证 n,Q≤2000;


对于100% 的数据, 保证 n,Q≤2×105;ri,qi≤2×105 。


运行限制

语言 最大运行时间 最大运行内存
C++ 1s 256M
C 1s 256M
Java 3s 256M
Python3 5s 256M

暴力做法:

#include <iostream>
#include <algorithm>
using namespace std;
int n,q;
int banjing[200005];
int xunwen[200005];
bool st[200005];
int  main(){
  cin>>n>>q;
  for(int i=1;i<=n;i++){
    cin>>banjing[i];
  } 
  for(int i=1;i<=q;i++){
    cin>>xunwen[i];
  }
  sort(banjing,banjing+n+1);
  int len=0;
  for(int i=1;i<=n;i++){
    for(int j=i+1;j<=n;j++){
      if(banjing[j]%banjing[i]==0){
        int b=banjing[j]/banjing[i];
        st[b]=1;
        len++;
      }
    }
  }
  for(int i=1;i<=q;i++){
    if(n==1&&xunwen[i]==1){
      cout<<"YES"<<endl;
    }else if(st[xunwen[i]]){
      cout<<"YES"<<endl;
    }else{
      cout<<"NO"<<endl;
    }
  }
  return 0;
}

寻找因式:

#include <iostream>
#include <algorithm>
#include <unordered_set>
using namespace std;
unordered_set<int> s;
int n,q;
int banjing[200005];
bool st[200005];
int  main(){
  ios_base::sync_with_stdio(false);     //提高cin和cout效率
  cin.tie(0);
  cin>>n>>q;
  for(int i=1;i<=n;i++){
    cin>>banjing[i];
  } 
  sort(banjing,banjing+n+1);
  for(int i=1;i<=n;i++){
    int v=banjing[i];
    for(int j=1;j*j<=v;j++){
      if(v%j==0){
        if(s.find(j)!=s.end()){   
          st[v/j]=1;
        }
        if(s.find(v/j)!=s.end()){
          st[j]=1;
        }
      }
    }
    s.insert(banjing[i]);
  }
  for(int i=1;i<=q;i++){
    int xunwen;
    cin>>xunwen;
    if(n==1&&xunwen==1){
      cout<<"YES"<<'\n';
    }else if(st[xunwen]){
      cout<<"YES"<<'\n';
    }else{
      cout<<"NO"<<'\n';
    }
  }
  return 0;
}

J:搬砖


问题描述

这天,小明在搬砖。


他一共有 n 块砖, 他发现第 i 砖的重量为 wi, 价值为 vi 。他突然想从这些 砖中选一些出来从下到上堆成一座塔, 并且对于塔中的每一块砖来说, 它上面 所有砖的重量和不能超过它自身的价值。


他想知道这样堆成的塔的总价值(即塔中所有砖块的价值和)最大是多少。


输入格式

输入共 n+1 行, 第一行为一个正整数 nn, 表示砖块的数量。


后面 n 行, 每行两个正整数 wi,vi 分别表示每块砖的重量和价值。


输出格式

一行, 一个整数表示答案。


样例输入

5
4 4
1 1
5 2
5 5
4 3

样例输出

10


样例说明

选择第 1、2、4 块砖, 从上到下按照2、1、4 的顺序堆成一座塔, 总价值 为 4+1+5=10


评测用例规模与约定

对于 20% 的数据, 保证 n≤10;


对于 100% 的数据, 保证n≤1000;wi≤20;vi≤20000 。


运行限制

最大运行时间:1s

最大运行内存: 512M

排序后,背包动态规划

#include <iostream>
#include <algorithm>
using namespace std;
int n;
int w;
int ans;
struct zhuan{
  int jiazhi;
  int zhongliang;
  bool operator<(const zhuan&rhd)const {
    return jiazhi+zhongliang<rhd.jiazhi+rhd.zhongliang;
  }
};
zhuan zhuant[1005];
int f[1010][50005];
int main() {
  cin>>n;
  for(int i=1;i<=n;i++){
    cin>>zhuant[i].zhongliang>>zhuant[i].jiazhi;
    w+=zhuant[i].zhongliang;
  }
  sort(zhuant+1,zhuant+n+1);
  for(int i=1;i<=n;i++){
    for(int j=0;j<=w;j++){
      f[i][j]=f[i-1][j];    //不选 
      if(j>=zhuant[i].zhongliang && j-zhuant[i].zhongliang<=zhuant[i].jiazhi)
      {
        f[i][j]=max(f[i][j],f[i-1][j-zhuant[i].zhongliang]+zhuant[i].jiazhi);
       } 
       ans=max(ans,f[i][j]);
    }
  }
  cout<<ans;
  return 0;
}

相关文章
|
1月前
|
算法 测试技术 C++
【动态规划算法】蓝桥杯填充问题(C/C++)
【动态规划算法】蓝桥杯填充问题(C/C++)
|
1月前
|
人工智能 算法 BI
第十四届蓝桥杯省赛大学C组(C/C++)三国游戏
第十四届蓝桥杯省赛大学C组(C/C++)三国游戏
|
1月前
|
人工智能 C++
第十四届蓝桥杯省赛大学B组(C/C++)整数删除
第十四届蓝桥杯省赛大学B组(C/C++)整数删除
|
5月前
|
存储 机器学习/深度学习 算法
第十五届蓝桥杯pb组国赛E题[马与象] (15分)BFS算法 详解
第十五届蓝桥杯pb组国赛E题[马与象] (15分)BFS算法 详解
61 3
|
1月前
|
机器学习/深度学习 算法 关系型数据库
第十五届蓝桥杯C++B组省赛
第十五届蓝桥杯C++B组省赛
79 14
|
1月前
|
算法 C++
2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解
2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解
37 5
|
5月前
|
存储 算法 测试技术
第十五届蓝桥杯大赛 国赛 pb组F题【括号与字母】(15分) 栈的应用
第十五届蓝桥杯大赛 国赛 pb组F题【括号与字母】(15分) 栈的应用
37 1
|
5月前
|
Java
2023届蓝桥杯大赛软件类国赛Java大学B组 互质 数论
2023届蓝桥杯大赛软件类国赛Java大学B组 互质 数论
37 1
|
5月前
|
存储 前端开发 算法
2016届蓝桥杯大赛软件类国赛Java大学B组 反幻方 暴力搜索
2016届蓝桥杯大赛软件类国赛Java大学B组 反幻方 暴力搜索
33 0
|
6月前
|
人工智能 算法 Java
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1005 数字游戏
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1005 数字游戏
109 0
下一篇
无影云桌面