试题题目

本题为编程题第二题
解题思路:
方法一:暴力求解
1、分析
   首先利用数组W[N]W[N]W[N]记录NNN块砝码的质量。
   模拟放取过程。先取第一块砝码放在天平上,再取第二块砝码,有三种情况选择:(1) 不放;(2) 放左边;(3) 放右边。第二块砝码摆放完成后,就能获得4种质量:(1) 不放砝码时:原质量;(2) 砝码放左边时:原质量减去第二块砝码质量的绝对值;(3) 砝码放右边时:原质量加上第二块砝码总质量;(4) 第二块砝码本身的质量。
   再上一步的基础上,取第三块砝码开始摆放,每种质量下也同样有三种情况。那么再第三块砝码摆放完成后,会得到3x4+1种质量。“+1”的原因是第三块砝码本身质量。
   依次循环类推,摆放完最后一块砝码后,将获得(3N−1)/2(3^N-1)/2(3N−1)/2种质量。但是当NNN的数很大时,质量种数也会非常庞大。所以在每取完一个砝码得出质量后,对质量数组进行去重处理,取下一个砝码时计算质量时不会被重复计算。

2、代码编写
   (1)、数组W[N]W[N]W[N]记录NNN块砝码的质量;
   (2)、循环取砝码,用二维数组V[i][j]V[i][j]V[i][j]记录放第i块砝码的质量;
      α\alphaα、 V[i][k++]V[i][k++]V[i][k++] = V[i−1][j]V[i-1][j]V[i−1][j] ;
      β\betaβ、 V[i][k++]V[i][k++]V[i][k++] = V[i−1][j]V[i-1][j]V[i−1][j] +++ W[i]W[i]W[i] ;
      γ\gammaγ、 V[i][k++]V[i][k++]V[i][k++] = V[i−1][j]V[i-1][j]V[i−1][j] −-− W[i]W[i]W[i] ;
      δ\deltaδ、 V[i][k++]V[i][k++]V[i][k++] = W[i]W[i]W[i] ;
   (3)、去重处理,遍历V[i][j]V[i][j]V[i][j],使得Value[V[i][j]]=1Value[V[i][j]]=1Value[V[i][j]]=1;
   (4)、对V[i][j]V[i][j]V[i][j]重新赋值,使得第i个数组内没有重复值。进入下一次循环,摆放下一个砝码。

个人题解C语言代码如下:

#include<stdio.h>
int N;
int W[105];
int V[105][100006];int main(){int i,j,times = 1;scanf("%d",&N);for(i=0;i<N;i++){scanf("%d",&W[i]);}int Wight=W[0];V[0][0] =W[0]; for(i=1;i<N;i++){Wight = Wight+W[i];int z,t=0,k = 0;    int Value[Wight+3];for(z=0;z<Wight+3;z++){Value[z]=0;}for(j=0;j<times;j++){V[i][k++] = V[i-1][j];V[i][k++] = V[i-1][j] + W[i];V[i][k++] = V[i-1][j] - W[i];}V[i][k] = W[i];for(z=0;z<k+1;z++){                  //去重处理 if(V[i][z]<0){Value[0-V[i][z]]=1;} else Value[V[i][z]]=1;}for(z=1;z<Wight+1;z++){if(Value[z]==1){V[i][t++]=z;}}times = t;}printf("%d",times);return 0;
}

优化代码,并使用算法提高代码运行速度与质量,采用动态规划思想。将上述代码中,不在统计计算出的质量,且不用数组Value[]Value[]Value[]中间转换的方法来去重,而是直接利用下标作为质量,直接为二维数组赋值,1或者0;1表示可以表示出下标的质量,反之0不能表示。

方法二:动态规划
1、思考
   看到样例说明中有这种参差不齐感觉的时候,想到的必然是使用算法来解决问题了,当然使用暴力求解也是可以的。对于砝码称重问题,考虑放砝码还是不放砝码,想到的是“““放还是不放”””,“““取还是不取”””等类似问题,所以使用的动态规划算法。
2、分析
   动态规划问题首先要确定状态,再确定状态转移方程,然后考虑边界初始化。

   (1)、状态:dp[i][j]dp[i][j]dp[i][j]表示前iii个砝码能否表示出质量jjj,能则变量值为111,不能则为000。

   (2)、状态转移方程:dp[i][j]=dp[i][j+a[i]]=dp[i][j−a[i]]=1dp[i][j] =dp[i][j+a[i]]=dp[i][j-a[i]]= 1dp[i][j]=dp[i][j+a[i]]=dp[i][j−a[i]]=1
  需要首先判断: 前 i−1i-1i−1 个砝码都能否表示出质量jjj 。
  若不能,那么第iii个砝码放在哪里都不合理,没有这个砝码都不能表出质量,再放一个该砝码,更不能确定前iii个砝码能表示出来的质量;
  若能,那么前iii个砝码也一定能够表示出质量jjj。则第iii个砝码也能放或不放,在这个基础之上在分别讨论第iii个砝码放在左边还是放右边,讨论情况如下:
     α\alphaα. 不放第iii个砝码。那前i−1i-1i−1能表示出质量jjj,前iii个砝码也能表示出质量jjj:dp[i][j]=1dp[i][j]=1dp[i][j]=1;
     β\betaβ. 放第iii个砝码,在右侧。那前i−1i-1i−1能表示出质量jjj,前iii个砝码也能表示出质量j+w[i]j+w[i]j+w[i]:dp[i][j+w[i]]=1dp[i][j+w[i]]=1dp[i][j+w[i]]=1;
     γ\gammaγ. 放第iii个砝码,在左侧。那前i−1i-1i−1能表示出质量jjj,前iii个砝码也能表示出质量j+w[i]j+w[i]j+w[i]:dp[i][j−w[i]]=1dp[i][j-w[i]]=1dp[i][j−w[i]]=1;注意j>w[i]j>w[i]j>w[i]时j−w[i]j-w[i]j−w[i];j<w[i]j<w[i]j<w[i]时w[i]−jw[i]-jw[i]−j。
     δ\deltaδ. 去除前面的砝码,放下第iii个砝码,即他自身的质量:dp[i][w[i]]=1dp[i][w[i]] = 1dp[i][w[i]]=1 ;

状态转移方程代码片段:

if(dp[i-1][j] == 1){                       // 在上一个砝码摆放后能得出的质量基础上。讨论三种情况dp[i][j] = 1;                      // 不放砝码。dp[i][j + W[i]] = 1;               // 把第i个砝码放在右边  就能表示出j+a[i]的重量 if(j-W[i]<0){dp[i][W[i] - j] = 1;} // 把第i个砝码放在左边  就能表示出|j-a[i]|的重量 else{        dp[i][j - W[i]] = 1;}
}

   (3)、边界初始化
  前iii个砝码一定可以表示出质量w[i]w[i]w[i],即dp[i][w[z]]=1dp[i][w[z]]=1dp[i][w[z]]=1;



个人题解C语言代码如下:

#include<stdio.h>
int N;
int W[105];
int dp[105][100006];
int main(){int i,j; scanf("%d",&N);for(i=0;i<N;i++){              //输入scanf("%d",&W[i]);}int Wight=W[0]; dp[0][W[0]] = 1;               //边界for(i=1;i<N;i++){              //核心Wight = Wight+W[i];  for(j=1;j<Wight+1;j++){if(dp[i-1][j] == 1){dp[i][j] = 1;dp[i][j + W[i]] = 1;if(j-W[i]<0){dp[i][W[i] - j] = 1;}else{        dp[i][j - W[i]] = 1;}}}dp[i][W[i]] = 1 ;}int ans=0;for(j=1;j<Wight+1;j++){       //统计if(dp[N-1][j] == 1){ans++;}}printf("%d",ans);return 0;
}

第十二届蓝桥杯省赛 C/C++大学B组 试题G:砝码称重相关推荐

  1. 2021年第十二届蓝桥杯 - 省赛 - C/C++大学A组 - D.路径

    2021年第十二届蓝桥杯 - 省赛 - C/C++大学A组 - D.路径 Ideas 算法:最短路径 数据结构:图 思路:根据规则构图,单源最短路径Dijkstra算法. 首先构图其实很简单,就是按照 ...

  2. 2021年第十二届蓝桥杯 - 省赛 - C/C++大学B组 - I.双向排序

    2021年第十二届蓝桥杯 - 省赛 - C/C++大学B组 - I.双向排序 Ideas 题目中给出了两种操作: 当 pi = 0 时,表示将 a1, a2, · · · , aqi 降序排列: 当 ...

  3. 2019 第十届蓝桥杯省赛C/C++大学B组 试题+题解

    第十届蓝桥杯省赛C/C++大学B组 试题+题解 第十届蓝桥杯大赛软件类省赛 C/C++ 大学 B 组 考生须知 考试开始后,选手首先下载题目,并使用考场现场公布的解压密码解压试 题. 考试时间为 4 ...

  4. 2021第十二届蓝桥杯国赛总结-java大学c组

    比赛结果 结果挺意外的,比赛中失误较多,送分题暴毙(审题失误),没把自己气死,结果算不错,但也挺可惜. 解答过程 1. 整数范围 答案:255 没想太多直接计算器算的,后来听符号位,但似乎不用考虑. ...

  5. 2021年第十二届蓝桥杯 - 省赛 - C/C++大学C组 - D.相乘

    Ideas 对于Python来说,都没有溢出,直接乘就完了. Code Python if __name__ == '__main__':for num in range(1, 1000000008) ...

  6. 第十届蓝桥杯国赛C/C++ 大学B组 试题C: 拼接

    试题 C: 拼接 本题总分:10 分 [问题描述] 小明要把一根木头切成两段,然后拼接成一个直角. 如下图所示,他把中间部分分成了 n × n 的小正方形,他标记了每个小正方 形属于左边还是右边.然后 ...

  7. 【蓝桥】2019第十届蓝桥杯省赛C/C++大学B组题目及感想(考场代码和思考)

    比赛时间:2019年3月24日礼拜天 上午9点到下午1点 说明 本文题目和代码为考试结束以后返回考场拷下来的 文中答案不保证正确(感觉错的地方还不少) 本文解题思路和代码只反映本人考场临场发挥情况,真 ...

  8. 第十二届蓝桥杯省赛第二场C++B组真题 【未完结】

    目录 3496. 特殊年份 [简单] 3490. 小平方 [简单] 3491. 完全平方数[简单数论] 3492. 负载均衡[小根堆模拟] 3496. 特殊年份 [简单] #include<bi ...

  9. 2019年第十届蓝桥杯 - 省赛 - C/C++大学A组 - G. 日期问题

    题目 标题:日期问题 小明正在整理一批历史文献.这些历史文献中出现了很多日期.小明知道这些日期都在1960年1月1日至2059年12月31日.令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月 ...

最新文章

  1. 递归/回溯:Subsets II求子集(有重复元素)
  2. php7.0 连接ftp,PHPstorm连接ftp
  3. php大号字体代码,支持中文字母数字、自定义字体php验证码代码
  4. UNIX再学习 -- 环境变量
  5. @JsonSerialize 使用:注解方式 实现条件判断属性值、条件修改属性值
  6. 在前端中如何在表格中最后一行加入输入框_UI设计进阶干货 — 如何制定UI规范...
  7. composer php 打包图片,composer 打包到 packagist
  8. 安装Ubuntu的那些事儿(续)
  9. JDK API 1.6.0中文版直接下载
  10. 三相异步电机----电机公式(三)
  11. R语言将两个矩阵数据进行相乘、抽取矩阵的正对角线元素值
  12. shell遍历ip执行特定功能
  13. PHP根据出生日期计算年龄
  14. 政府行业数据保护方案
  15. linux 内存映射-ioremap和mmap函数
  16. 3D建模 UG8.0 32位安装过程
  17. asp.net控件,服务器标记的格式不正确问题解决方法
  18. Pip/python-如何查看已安装的包有哪些版本?如何查看某个包存在哪些版本?pip list-pip freeze-pip show package
  19. 火车头采集之采集规则编写
  20. 05-【gorm】GORM Model FindFirstWhere等查询函数的区别

热门文章

  1. 基于ssm的一个一个众筹系统平台
  2. 5大系统清道夫帮你整理安卓设备上的臃肿软件
  3. java提示系统找不到指定路径怎么解决?
  4. 拥抱520,感性去爱,理性成长
  5. Mysql数据库日常使用备注
  6. 安装WSL2的踩雷历程
  7. 软RAID 0的技术概要及实现 v0.1b
  8. 服务器系统安装优盘启动工具,u盘启动大师在Win10上安装和卸载远程服务器管理工具的方法...
  9. 基于Kinect体感器控制的机械臂项目记录
  10. 深度:中老年网民电商渗透率超40%,拼多多/淘宝/京喜/有赞如何布局老年电商市场?