1284: Gold Medal

题目

  有N个砝码,重量为:3i-1(1<=i<=N),有一块重量为 W 的金牌。现在将金牌放在天平的左边。你需要将砝码放在左边右边使得天平平衡,如果不能平衡输出"No way!",N个砝码不需要全部用完。更多内容点击标题。

参考

果7的博客

分析

  说实话,我也没想到这种做法,看的参考博客才明白的。(感觉他有部分代码处理的不是很好,可能是语言不同的关系吧。)
  没见过这类题的话,说实话不容易一下子想到居然和进制居然有一点点关系。
  不得不说砝码的重量很灵性。我们可以尝试在这里入手。首先将金牌的重量 W 转成三进制的,由于长度较大所以直接用数组保存比较好(我用的byte[])。下面举个例子:
输入:

4 16

输出:

LEFT:3 9
RIGHT:1 27

步骤:

通俗讲:
将金牌分成9,6,1三部分(提醒:金牌是固定放在左边的。16的三进制为121),然后发现砝码中有1,
于是就把1放在右边和左边的1平衡,然后继续,发现没有重量为6的砝码,但是你发现有重量为3和9的砝码,
于是就把3放左边,9放在右边,这样就与左边的6平衡了。继续,左边还有9,可是你还剩一个砝码(27),
根本不能平衡。于是你尝试将上一步中的9放在左边,此时左边有3,9和金牌的16一共是28,右边只有1,
但是还剩一个砝码(27),放在右边刚刚好。
代码流程:
16转成三进制为:121  // 左边高位,右边低位
第0位是'1',所以3^0=1放在右边
第1位是'2',权重是3^1=3,所以2*3=6,因为6不是3的幂,可是6=9-3,9和3都是3的幂,于是将3放
在左边,然后将121变成221
第2位是'2',权重是3^2=9,所以2*9=18,因为18不是3的幂,可是18=27-9,27和9都是3的幂,于是
将9放在左边,然后将221变成1221
第4位是'1',权重是3^3=27,所以1*27=27,是3的幂,于是将27放在右边。

代码

/*** time 741ms* @author PengHao* @version A1.0* @date 2019-04-29 下午5:39:25* Environment:    Windows 10* IDE Version:    Eclipse 2019-3* JDK Version:    JDK1.8.0_112*/import java.io.BufferedInputStream;
import java.util.Scanner;public class Main {/*** @Field <code>wTernary</code> W的三进制字节数组,下标从0开始*/private byte[] wTernary;/*** @Field <code>leftArr</code> 左边的砝码情况*/private byte[] leftArr;/*** @Field <code>rightArr</code> 右边的砝码情况*/private byte[] rightArr;/*** @Field <code>tab</code> 3的n次幂(0<=n<=29),下标从0开始*/private long[] tab;/*** @Field <code>ARR_LENGTH</code> 数组长度30*/private int ARR_LENGTH = 30;public Main() {Scanner sc = new Scanner(new BufferedInputStream(System.in));initTab(); // 初始化int N, W;while (sc.hasNext()) {N = sc.nextInt();W = sc.nextInt();wTernary = toTernary(W); // 转换成三进制weighing(wTernary); // 称重if (numOfWeights() <= N) {output(); // 输出} else {System.out.println("No way!");}System.out.println(); // 每组数据末尾空一行}sc.close();}/*** Initialize <code>tab[]</code>* * @see #tab*/private void initTab() {tab = new long[ARR_LENGTH];tab[0] = 1;for (int i = 1; i < ARR_LENGTH; i++) {tab[i] = tab[i - 1] * 3;}}/*** Converts an integer to a ternary byte array* * @param x 整数* @return x的三进制字节数组*/private byte[] toTernary(int x) {byte[] y = new byte[ARR_LENGTH];for (byte i = 0; i < ARR_LENGTH && x > 0; i++) {y[i] = (byte) (x % 3);x /= 3;}return y;}/*** @param x 需要称的重量* @see #leftArr* @see #rightArr*/private void weighing(byte[] x) {leftArr = new byte[ARR_LENGTH]; // 保存左边砝码rightArr = new byte[ARR_LENGTH]; // 保存右边砝码for (int i = 0; i < ARR_LENGTH; i++) {switch (x[i]) {case 1:rightArr[i] = 1; // 砝码3^i放到右边break;case 2:leftArr[i] = 1; // 砝码3^i放到左边x[i + 1]++; /// 要研究一下自增和赋值谁快break;case 3:x[i + 1]++;break;default:}}}/*** @return 砝码个数*/private int numOfWeights() {int num; // 砝码个数for (num = ARR_LENGTH - 1; num >= 0; num--) {if (0 != leftArr[num] || 0 != rightArr[num]) {num++;break;}}return num;}/*** Output*/private void output() {outputArr("LEFT:", leftArr);outputArr("RIGHT:", rightArr);}/*** @param LR  左右?* @param arr 需要输出的砝码*/private void outputArr(String LR, byte[] arr) {boolean first = true; // 是不是第一个砝码System.out.print(LR);for (int i = 0; i < ARR_LENGTH; i++) {if (1 == arr[i]) {if (first) {first = false;} else {System.out.print(" "); // 不是这一边的第一个砝码,要输出空格}System.out.print(tab[i]); // 输出砝码重量}}System.out.println();}public static void main(String[] args) {new Main();}
}

写在最后:

  1. 如需转载,请于首页至少注明链接形式的wowpH的博客这几个字;
  2. 代码原创,如需公开引用,不能删除首行注释(作者,版本号,时间等信息)。
  3. 如果有疑问欢迎评论留言,尽量解答。

转载于:https://www.cnblogs.com/wowpH/p/11060804.html

WUTOJ 1284: Gold Medal(Java)相关推荐

  1. 何时还完房贷-自由还款还款信息计算(JAVA)

    何时还完房贷-[自由还款]信息计算(JAVA) 背景 当今社会贷款买房,已经成为大多数人的必然选择.贷款方式可以选择公积金贷.商贷.组合贷,还款方式可以选择等额本息.等额本金.自由还款方式等.当前网络 ...

  2. 常惠琢 201771010102《面向对象程序设计(java)》第七周学习总结

    实验七 继承附加实验 实验时间 2018-10-11 1.实验目的与要求 (1)进一步理解4个成员访问权限修饰符的用途: (2)掌握Object类的常用API用法: (3)掌握ArrayList类用法 ...

  3. 建立与ftp服务器的连接——完成版(java)

    建立与ftp服务器的连接--完成版(java) // ftp 程序Ftp.java // 此程序的功能是建立与ftp服务器的连接并实现文件传输 // 使用方法:java Ftp 服务器地址 //启动示 ...

  4. 海康摄像头的二次开发(java)

    海康摄像头的二次开发(java) 我第一次接触海康摄像头的二次开发的项目,一开始的时候摸不清套路,走了不少弯路,现在准备把我的一些经验留下来,让大家参考一下. 1.首先到海康的官网下载设备网络SDK: ...

  5. 《编程导论(Java)#183;1.4.1 范式》

    这个楼主,是我的学生么?2013年写的! 嗯."编程范式或许是学习不论什么一门编程语言时要理解的最重要的术语".这句话早在2005年出版<Java程序设计>(宋中山,严 ...

  6. 201771010106东文财《面向对象程序设计(java)》实验12

    实验十二  图形程序设计 实验时间 2018-11-14 1.实验目的与要求 (1) 掌握Java GUI中框架创建及属性设置中常用类的API: (2) 掌握Java GUI中2D图形绘制常用类的AP ...

  7. 2018面向对象程序设计(Java)第3周学习指导及要求

    2018面向对象程序设计(Java) 第3周学习指导及要求(2018.9.11-2018.9.16)   学习目标 适应老师教学方式,能按照自主学习要求完成本周理论知识学习: 掌握Java Appli ...

  8. 一些面试题(JAVA)

    一些面试题(JAVA) 01.通过什么参数分配Java内存使用? java -Xms128m -Xmx512m 02.Treemap和Hashmap区别是什么? TreeMap对Key进行排序,而Ha ...

  9. 达拉草201771010105《面向对象程序设计(java)》第十六周学习总结

    达拉草201771010105<面向对象程序设计(java)>第十六周学习总结 第一部分:理论知识 1.程序与进程的概念: (1)程序是一段静态的代码,它是应用程序执行的蓝 本. (2)进 ...

最新文章

  1. Nginx一点事儿(一)
  2. sprite的大小 unity_[Unity]SpriteShape与atlas的小坑
  3. java.io.CharConversionException isHexDigit JS转码问题
  4. 代码签名证书,让软件真正拥有姓名!
  5. Centos7 Yum安装 PHP5.5,5.6,7.0
  6. HDU 1828:Picture(扫描线+线段树 矩形周长并)
  7. 华为云WeLink:智能工作空间,联接无限想象
  8. tree工具类 TreeUtils.java
  9. Nginx+Memcached+Tomcat集群配置
  10. 电流测试c语言算法,真有效值的定义及其C语言算法推导
  11. 怎么批量将DWG文件转换PDF文件
  12. (过桥问题)小明一家过一座桥,过桥时是黑夜,所以必须有灯
  13. JS:关系运算符(>大于、>=大于等于、<小于、<=小于等于)
  14. java游戏为什么_JAVA能不能开发大型游戏?为什么?
  15. Xposed模块开发
  16. 55 - 字符流中第一个不反复的字符
  17. 2020大学生网络安全知识总决赛模拟题错题集(9)
  18. 实现用户端的充值、修改密码、查看个人信息、保存用户的信息到文件操作
  19. QueryWrapper方法
  20. 计算机设备维护保养和网络巡检,弱电设备的维护保养及巡检管理制度

热门文章

  1. linux配置chrony时间同步
  2. K8S部署工具:KubeOperator集群部署
  3. 解决HBase RegionServer进程还在,但是显示已经dead了
  4. loadrunner脚本设计:事务函数的使用
  5. Linux time ls命令:用户态内核态分别占用多长时间
  6. scala 的39个关键字
  7. Docker cAdvisor安装
  8. spring mvc工作原理及组件说明
  9. 基于 abp vNext 和 .NET Core 开发博客项目 - 集成Hangfire实现定时任务处理
  10. Python常用技巧了解一下?