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. 如果有疑问欢迎评论留言,尽量解答。

WUTOJ 1284: Gold Medal(Java)的更多相关文章

  1. 如何夯实(Java)编程基础,并深入学习和提高

    如何夯实(Java)编程基础,并深入学习和提高? 240赞同反对,不会显示你的姓名 匿名用户 240 人赞同 多学习...网上自学的学习网站很多,见以下榜单~一.汇总榜单: 公开课_学习网站导航 收录 ...

  2. TCL校园招聘——软件开发工程师(java) 只招5个。。。

    简介 TCL集团股份有限公司创立于1981年,是全球性规模经营的消费类电子企业集团之一,广州2010年亚运会合作伙伴,总部位于广东省惠州市仲恺高新区TCL科技大厦.旗下拥有TCL集团.TCL多媒体科技 ...

  3. UEditor上传图片到七牛云储存(java)

    我们的网站一般放在虚拟空间或者服务器上,图片如果存在本地目录,会占用很多空间和流量,还增加了负担,好的办法是把图片存放到云储存服务里面,平时用url去拿 云储存:普遍说又拍云和七牛比较好,看到七牛免费 ...

  4. 开源工作流 Bonita BPM (JAVA)

    Bonita BPM 开源工作流 Bonita BPM  (JAVA) http://www.bonitasoft.com/

  5. ZeroMQ(java)中对IO的封装(StreamEngine)

    哎,各种各样杂七杂八的事情...好久没有看代码了,其实要搞明白一个与IO相关的框架,最好的办法就是把它的I/0的读写两个过程搞清楚...例如在netty中,如果能将eventLoop的运行原理搞清楚, ...

  6. 编译哈工大语言技术平台云LTP(C++)源码及LTP4J(Java)源码

    转自:编译哈工大语言技术平台云LTP(C++)源码及LTP4J(Java)源码 JDK:java version “1.8.0_31”Java(TM) SE Runtime Environment ( ...

  7. 随机产生30个两个两位数相加的题目(java)

    编程思路: 1首先遇到JAVA产生随机数的问题. 2把产生的随机数设定范围. 3把划分的范围再分四个小区段分别对应四则运算法则加减乘除. 4打印输出. 题目源代码(Java) package coun ...

  8. Android(java)学习笔记267:Android线程池形态

    1. 线程池简介  多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.     假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...

  9. MongoDB的update有关问题(JAVA)——如何一次更新所有的相同记录

    MongoDB的update问题(JAVA)——怎么一次更新所有的相同记录用如下这个函数:public WriteResult update(DBObject q,  DBObject o,  boo ...

随机推荐

  1. avalon.js中使用owl-carousel轮播图

      <?php if($banners){?> <div class="ms-controller" ms-controller="bannerShow ...

  2. pimpleFoam求解器 vs simpleFoam求解器 vs pisoFoam求解器 vs icoFoam

    翻译自:CFD-online 帖子地址:http://www.cfd-online.com/Forums/openfoam-solving/68072-pimplefoam-vs-simplefoam ...

  3. Spring源代码分析:PropertiesLoaderSupport

    概述 Spring PropertiesLoaderSupport是一个抽象基类,它抽象了从不同渠道加载属性的通用逻辑,以及这些属性应用优先级上的一些考虑.它所提供的这些功能主要供实现子类使用.Spr ...

  4. 2019 DDCTF 部分writeup

    网上的wp已经很多了,但wp普遍很简略.我尽量写的详细一点. 一.WEB 滴~ 拿到题目后首先右键查看源代码,发现图片是以base64传送的 而且看url发现里面应该是包含了文件名,并且用了某个编码. ...

  5. 命令行运行Python脚本时传入参数的三种方式

    原文链接:命令行运行Python脚本时传入参数的三种方式(原文的几处错误在此已纠正) 如果在运行python脚本时需要传入一些参数,例如gpus与batch_size,可以使用如下三种方式. pyth ...

  6. 计算机基础——Java笔记一

            电子管-晶体管 摩尔定律 18个月变一次       贝尔实验室 C语言是基础.芯片领域软件领域 机器语言 ——汇编语言——高级语言 (面向过程,面向对象)   基本的逻辑怎么用代码实 ...

  7. LayUI使用弹窗重载父级数据表格的两种方法

    参考LayUI官方文档,在子窗口中重载父级数据表格找到以下两种方法: 1.子窗口中重载:在子窗口中直接调用父级talbe的reload方法. $("body").on(" ...

  8. javascript 的垃圾回收机制讲一下

    定义:指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束. 像 C 这样的编程语言,具有低级内存管理原语,如 malloc()和 free().开发人员使用这些原语显式地对操作系统的内存进行 ...

  9. How can I get a Netty server to reload a TLS certificate when it is renewed?

    java - How can I get a Netty server to reload a TLS certificate when it is renewed? - Stack Overflow ...

  10. Win10系统安装VMware-viclient-6.0无响应问题解决方法

    背景:笔记本重做系统升级至Win10系统后,由于工作需要,得安装VMware-viclient-6.0软件进行远程连接. 问题:没有出现网上那种各种报错情况,只是在点击“安装”按钮的时候没弹出任何等待 ...