WUTOJ 1284: Gold Medal(Java)
生活随笔
收集整理的這篇文章主要介紹了
WUTOJ 1284: Gold Medal(Java)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1284: Gold Medal
如需轉載,請于首頁至少注明鏈接形式的wowpH的博客這幾個字; 代碼原創,如需公開引用,不能刪除首行注釋(作者,版本號,時間等信息)。 如果有疑問歡迎評論留言,盡量解答。
題目
??有N個砝碼,重量為:3i-1(1<=i<=N),有一塊重量為 W 的金牌。現在將金牌放在天平的左邊。你需要將砝碼放在左邊或右邊使得天平平衡,如果不能平衡輸出"No way!",N個砝碼不需要全部用完。更多內容點擊標題。
參考
果7的博客
分析
??說實話,我也沒想到這種做法,看的參考博客才明白的。(感覺他有部分代碼處理的不是很好,可能是語言不同的關系吧。)
??沒見過這類題的話,說實話不容易一下子想到居然和進制居然有一點點關系。
??不得不說砝碼的重量很靈性。我們可以嘗試在這里入手。首先將金牌的重量 W 轉成三進制的,由于長度較大所以直接用數組保存比較好(我用的byte[])。下面舉個例子:
輸入:
輸出:
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();} }寫在最后:
轉載于:https://www.cnblogs.com/wowpH/p/11060804.html
總結
以上是生活随笔為你收集整理的WUTOJ 1284: Gold Medal(Java)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 信步漫谈之Git—环境搭建及入门
- 下一篇: 北汽中核中铁多名官员被查,沙棘主要调节什