2019第十届蓝桥杯大赛青少年创意编程省赛C++组试题解析

2019-06-05 21:49:15

水平有限,如有不当请不吝赐教,万分感谢

水下探测器
水下探测器可以潜入湖中在任意水深进行科学探索。
湖水的最大深度为 h 米,即它在湖底时到水面的距离,0<=h<=100;
探测器最初的水下深度为 s 米,0<=s<=100;
当探测器不在水面(当前深度大于 0)时,每个 u 指令可使它上浮 1 米,而当探测器在水面时,u 指令是无效的;
当探测器不在湖底(当前深度小于 h)时,每个 d 指令可使它下沉 1 米,而当探测器在湖底时,d 指令是无效的;
在执行到无效指令时,探测器不做任何操作而继续执行下一指令。
编程实现:
根据给定的 h、s 和一个指令序列(由字符 u、d 组成的字符串,长度不超过 100),求出执行完整的指令序列后,探测器的水下深度。
输入:
第一行:h 和 s,以空格分开。0<=s<=h<=100
第二行:长度不超过 100 的指令字符串,串中仅包含字母 u 或 d
输出:
代表探测器在执行指令后的水下深度的数字。
样例输入:
9 1
uduudd
样例输出:
2

样例数据分析:
水深9米,探测器在水下1米处,
字符u代表向上1米,探测器上浮到0米处
字符d代表向下1米,探测器下沉到1米处
字符u代表向上1米,探测器上浮到0米处
字符u代表向上1米,探测器已经在水面,不能上浮,依然在0米处
字符d代表向下1米,探测器下沉到1米处
字符d代表向下1米,探测器下沉到2米处
最终结果为2
考察知识:
基础语法,字符串,循环,条件判断
参考代码:
#include 
using namespace std;

int main(){
 int h,s;
 string str;
 cin>>h>>s>>str;
 for(int i=0;i   if(str[i]=='u'){
   if(s>0){
    s--;
   }
  }else{
   if(s     s++;
   }
  }
 }
 cout< }

//蓝桥杯组委会:16601195122 田老师
//作者:17704313221 宫老师
//[明创科技教育](http://www.jilinmingchuang.com)
//[测评练习系统](http://oj.jilinmingchuang.com)
12345678910111213141516171819202122232425

猫吃鱼
明明家从 1 号站点出发,开车去旅游,一共要经过 n 个站点,依次为 2、3……n。
由于明明带上了心爱的小猫,在每个站点都要为小猫提供一条鱼用做美餐(包括 1 号站点)。
除了 1 号站点只能吃 1 号站点买的鱼,其他站点既可以吃当地买的鱼,也可吃之前经过的站点买了存入车载冰箱中的鱼。
但车载冰箱消耗的电能来自汽油,所以每条鱼用冰箱保存到下一站的费用与各个站点的汽油价格有关。
为使问题简化,我们约定:
(1)车从某站开出时油箱中都是此站点刚加的汽油。
(2)车载冰箱能容纳一路上需要的所有鱼。
即:每条鱼的费用既包括购买时的费用,也包括用冰箱保存鱼的费用。
编程实现:
为了降低小猫吃鱼的总代价,明明预先上网查到了这 n 个站点的鱼价和汽油价格。并据此算出每个站点买一条鱼的费用以及从该站点到下一站用冰箱保存一条鱼的费用。你能帮明明算出这一路上小猫吃鱼的最小总费用吗?
输入:
第一行:站点数 n,1 接下来的 n 行:每行两个以空格分隔的正整数,表示:这一站买一条鱼的费用,以及从这一站把每条
鱼保存到下一站的费用,两个费用均为小于 10000 的正整数。
输出:
最小总费用,是一个正整数。
样例输入:
5
6 3
7 1
3 2
8 3
9 5
样例输出:
29

样例数据分析:
第一行数据 5 ,代表一共5站
第二行数据6 3 代表本站购买鱼6元,运费3元,第一站必须一定先购买一条 总花费6元
第三行数据7 1 代表本站购买鱼7元,运费1元,从上一站最小花费+运费9元,大于本站购买的费用7,所以选择从本站购买鱼,总花费 6+7=13元
第四行数据3 2 代表本站购买鱼3元,运费2元,从上一站最小花费+运费8元,大于本站购买的费用3,所以选择从本站购买鱼,总花费 6+7+3=16元
第五行数据8 3 代表本站购买鱼8元,运费3元,从上一站最小花费+运费5元,小于本站购买的费用8,所以选择从上一站花费加上本站运费,总花费6+7+3+5=21元
第六行数据9 5 代表本站购买鱼9元 运费5元,从上一站最小花费+运费8元,小于本站购买的费用9,所以选择从上一站花费加上本站运费,总花费6+7+3+5+8=29元
最终总花费为29元
考察知识:
数组,递推算法
参考代码:
#include 
using namespace std;
int main(){
 int n;
 cin>>n;
 int a[n],b[n];
 for(int i=0;i   cin>>a[i]>>b[i];
 }
 int min=99999,t=0;
 for(int i=0;i   if(min>a[i]){
   min=a[i];
  }
  t=t+min;
  min=min+b[i];
 }
 cout< }
//蓝桥杯组委会:16601195122 田老师
//作者:17704313221 宫老师
//[明创科技教育](http://www.jilinmingchuang.com)
//[测评练习系统](http://oj.jilinmingchuang.com)
1234567891011121314151617181920212223

评选最佳品牌
n 个评委投票,在 m 个商品中评选一个最佳品牌。
评选采用多轮淘汰制,即:每轮投票,淘汰掉得票最少的候选品牌(得票并列最少的品牌一起淘汰)。
如此一轮轮淘汰下去,如果最后只剩下一个品牌当选,即告评选成功。
但如果在某轮投票中,当时未被淘汰的所有候选品牌(大于等于两个品牌)都并列得票最少,即告评选失败。
如果评选成功就输出当选品牌号。否则输出最后一轮评选时唯一选票数的相反数。
在评选流程中,每个评委的态度都可用一个序列来表示;例如当 m=5 时,某评委的评选态度序列为:3、
5、1、2、4,则表示该评委:优先投 3 号,当 3 号被淘汰时投 5 号,当 3 和 5 都被淘汰时投 1,当 3、5、1 都被淘汰时投 2,仅剩 4 号时才投 4 号品牌的票。
选票的序列中可以表示弃权,用 0 来表示,例如当 m=5 时,某评委的评选态度序列为:3、5、0,则表示该评委:优先投 3 号,当 3 号被淘汰时投 5 号,其它情况下不投任何品牌的票。
编程实现:
请你编一个程序,模拟各轮投票的过程,得到评选结果。
输入:
第一行:m(0 输出:
评选结果。
样例 1 输入:
3 4
123
213
132
10
样例 1 输出:
1
样例 2 输入:
3 4
321
213
231
312
样例 2 输出:
-2
样例数据分析:


样例1:
第一行3 4 代表3个品牌,4个评委

第一轮投票,3个评委优先选择1号品牌,1个评委选择2号品牌,品牌3得票最少,淘汰掉
第二轮投票,3个评委优先选择1号品牌,1个评委选择2号品牌,品牌2得票最少,淘汰掉,淘汰2号品牌后,只剩一个1号品牌,1号品牌胜出
最终结果 1

样例2:
第一行3 4 代表3个品牌,4个评委

第一轮投票,2个评委选择2号品牌,两个评委选择3号品牌,1号得票最少,淘汰掉
第二轮投票,2个评委选择2号品牌,两个评委选择3号品牌,由于只剩下两个品牌,且并列最少,都是2票,代表评选失败,需要输出最后一轮票数2的相反数-2
最终结果 -2
考察知识:
字符串,桶排序,模拟算法
参考代码:
#include 
using namespace std;

int main(){
 int m,n;
 cin>>m>>n;
 string str[n+1];
 for(int i=1;i<=n;i++){
  cin>>str[i];
 }
 int a[m+1];//记录投票过程,-1代表淘汰
 while(true){
  for(int i=1;i<=m;i++){
   //重新计票,所有没有被淘汰的票数归零
   if(a[i]!=-1)a[i]=0;
  }
  for(int i=1;i<=n;i++){
   //计票
   string s=str[i];
   for(int j=0;j     char t=s[j]-'0';
    if(t==0){
     //如果为0 说明弃权
     break;
    }else{
     //不为0,则代表要给t投票,如果t没有被淘汰则给它投票
     if(a[t]>=0){
      a[t]=a[t]+1;
      break;
     }
    }
   }
  }
  
  int min=m+1;
  int max=0;
  for(int i=1;i<=m;i++){
   if(a[i]>=0){
    if(min>a[i]) min=a[i];
    if(max    }
  }
  
  if(max>min){
   //最大值比最小值大,需要将所有最小值的淘汰
   for(int i=1;i<=m;i++){
    if(a[i]==min)a[i]=-1;
   }
  }else{
   //最大值和最小值相等说明平票
   int count=0;
   int dx=0;
   for(int i=1;i<=m;i++){   
    if(a[i]==max){
     count++;
     dx=i;
    }
   }
   if(count>1){
    //如果数量多,说明评选失败
    cout<<0-max;
   }else{
    cout<    }
   break;
  }
 }
 cin>>m;
}
//蓝桥杯组委会:16601195122 田老师
//作者:17704313221 宫老师
//[明创科技教育](http://www.jilinmingchuang.com)
//[测评练习系统](http://oj.jilinmingchuang.com)
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273

最大购物优惠
小惠听说超市正在打折促销,要制订一个得到最大优惠的购物计划。
小惠的体力可以提起 w 单位重量的东西,还有一个能装 V 个单位体积的购物袋,并详细了解了各打折商品的重量、体积及此商品实际优惠的金额。她想在自己体力的限度和购物袋容积限度内,尽可能多地得到购物优惠。
超市规定这些打折商品每种只能购买一件。
编程实现:
请你编写程序,制定一个购买商品的计划,求出小惠能得到的最大优惠金额和实际应购买的各商品序号。
输入:
第一行:依次为 w、v 和 n(n 为商品种类数),所有数值均为不超过 100 的正整数
接下来的 n 行:每行有三个整数,依次为某种商品的重量、体积和让利金额,数值间以空格分开,所有数值均为不超过 100 的正整数
输出:
第一行:小惠能够得到的最大让利金额
第二行:依次为从小到大排列的商品序号,序号从 1 开始,序号间用空格分开。若第二行输出的序列不唯一,则输出其最小字典序。
样例输入:
10 9 4
8 3 6
5 4 5
3 7 7
4 5 4
样例输出:
9
2 4

样例数据分析:
第一行数据 10 9 4,代表最多能提起重量10,购物袋体积9,4种商品
第二行数据代表 第1件商品重量8 ,体积3,让利金额4
第三行数据代表 第2件商品重量5 ,体积4,让利金额5
第四行数据代表 第3件商品重量3 ,体积7,让利金额7
第五行数据代表 第4件商品重量4 ,体积5,让利金额4
创建一个三维数组 yh[n+1][w+1][v+1] 记录在第n个物品,w重量,v体积时 最优策略

只考虑一个物品的时候(纵向代表重量,横向代表体积,数据代表最大优惠)

考虑前两个物品的时候

考虑前三个物品的时候

考虑前四个物品的时候

最终结果,最大优惠为9,同时需要额外记录在在不同商品数量,不同重量和体积的情况下,如何购买商品
考察知识:
动态规划,二维费用的背包问题,在01背包问题的基础上增加一个费用维度
状态转移方程:
yh[i][j][k]=max(yh[i-1][j][k],yh[i-1][j-w[i]][k-v[i]]+n[i])
经典01背包问题解(https://blog.csdn.net/qq_38410730/article/details/81667885)
参考代码:
#include 
using name

  • Copyright© 2015-2021 长亭外链网版权所有
  • QQ客服

    需要添加好友

    扫码访问本站