1. 程式人生 > >巧用三進位制解決天平稱重問題

巧用三進位制解決天平稱重問題

1.問題描述:
 用天平稱重時,我們希望用盡可能少的砝碼組合稱出儘可能多的重量。
 如果有無限個砝碼,但它們的重量分別是1,3,9,27,81,……等3的指數冪
 神奇之處在於用它們的組合可以稱出任意整數重量(砝碼允許放在左右兩個盤中)。
 本題目要求程式設計實現:對使用者給定的重量,給出砝碼組合方案,重量<1000000。
 例如:
 使用者輸入:
 5
 程式輸出:
 9-3-1
 使用者輸入:
 19
 程式輸出:
 27-9+1

 要求程式輸出的組合總是大數在前小數在後。
 可以假設使用者的輸入一定是一個大於0的整數

2.思路:

例如十進位制數字17轉換成三進位制數字為122

先把字串進行翻轉,翻轉的目的是為了在轉換成字元陣列之後進行更好的進位處理

翻轉後字串變成221,分別是低位像高位進行進位,第一個字元2向高位進一位,那麼該位上應該要減去1,變成-131(17)

接下來進行第二個字串3的處理,向上高位進一位應該是變成0,字串變成-102(17)

進行第三個字元的處理向上進一位然後該位需要減去1,變成-10-11,最後的話把三進位制位上的數字都改為-1和1

其中進行動態增加字串可以使用ArrayList的add方法,將元素插入到指定位置add(int index, Integer element)

當插入的索引的位置處已經有值之後那麼原來的索引及元素都會後移一位再把新的元素插入到這個指定的索引處

具體的程式碼如下:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        //從控制檯輸入一個十進位制整數
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        solve(N);
    }

    private static void solve(int n) {
        //把n轉換成三進位制而且翻轉字串並且轉換成字元陣列
        //翻轉字串的目的是為了更好的進行進位的操作
        final String str = Integer.toString(n,3);
        List<Integer> list = new ArrayList<>();
        char a[] = new StringBuilder(str).reverse().toString().toCharArray();
        for(int i = 0;i<a.length;i++){
            if(a[i]=='2'){

                //全部都是往0這個索引處增加元素值那麼這個相當於棧,先插入的元素排列在後面
                list.add(0,-1);
                if(i==a.length-1){
                    list.add(0, 1);
                }
                //a[i+1]++必須是當i不是在a.length-1的時候加上的,否則會導致陣列越界
                else{

                    //這裡特別要注意陣列越界的問題,所以需要使用else的邏輯來處理
                    a[i+1]++;
                }
                //有可能加1之後某些位上的數字變成3
            }else if(a[i]=='3'){
                list.add(0, 0);
                if(i==a.length-1){
                    list.add(0, 1);
                }else{
                    a[i+1]++;
                }
            }
            else{
                list.add(0, a[i]-'0');
            }
        }
        StringBuilder sb = new StringBuilder();
        for(int i = 0;i<list.size();i++){
            if(list.get(i)==1){
                sb.append("+").append((int)Math.pow(3, list.size()-i-1));
            }
            if(list.get(i)==-1){
                sb.append("-").append((int)Math.pow(3, list.size()-i-1));
            }
        }
        System.out.println(sb.toString().substring(1));
    }
}
 

相關推薦

解決天平問題

1.問題描述:  用天平稱重時,我們希望用盡可能少的砝碼組合稱出儘可能多的重量。  如果有無限個砝碼,但它們的重量分別是1,3,9,27,81,……等3的指數冪  神奇之處在於用它們的組合可以稱出任意整數重量(砝碼允許放在左右兩個盤中)。  本題目要求程式設計實現:對使用者給

Travelling (+狀壓dp)

題目連結 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 inline ll read(){ 5 int x=0,f=1;char ch=getchar();

、精度,Java的型別轉換

進位制的表示: 0b010 :  二進位制表示形式:前面+0n 0100  : 八進位制表示形式: 前面+0 0x001 : 16進製表示形式:前面+0x 計算機以補碼的方式進行運算 進位制的轉換: 10進位制轉換成任意進位制: 除基倒取餘,結果從按餘數下往上寫

【2018/09/15】T1-拆分-平衡

題目描述 平衡三進位制,是一種以 3 為基數,-1(以下用T表示)、0、1 為基本數碼的進位制。由於 -1 的引入,這種進位制不需要額外的符號就能直接表示負數。正因為這一點,使得平衡三進位制在加減法和乘法方面的效率要比二進位制高。 美國著名計算機學家高德納在《程式設計的藝

【2018/09/15測試T1】【SOJ 1804】平衡

【題目】 題目描述: 平衡三進位制,是一種以  為基數,(以下用 T 表示)、、 為基本數碼的進位制。由於  的引入,這種進位制不需要額外的符號就能直接表示負數。正因為這一點,使得平衡三進位制在加減法和乘法方面的效率要比二進位制高。 美國著名計算機學家高德納在《程式設計

1111: [POI2007]四天平Wag

1111: [POI2007]四進位制的天平Wag 連結 題意:   用一些四進位制數,相減得到給定的數,四進位制數的數量應該儘量少,滿足最少的條件下,求方案數。 分析:   這道題拖了好久啊。   參考Claris的部落格。 首先將四進位制數轉化為四進位制數。 一種的可行構造方案是四進位制數

HDU---Travelling(狀態壓縮)

題意:題意:Mr ACMer想要進行一次旅行,他決定訪問n座城市。Mr ACMer 可以從任意城市出發,必須訪問所有的城市至少一次,並且任何一個城市訪問的次數不能超過2次。n座城市間有m條道路,每條道路都有一個費用。求Mr ACMer 完成旅行需要花費的最小費用。如果不能

hdu3001(狀壓)

題目大意: 現在給你一個有n個點和m條邊的圖,每一條邊都有一個費用,每個點不能經過超過兩次,求所有點至少遍歷一次的最小費用 其中n<=10 m沒有明確限制(肯定不會超過1e5) 一看到這個資料範圍,第一想法就是狀壓QWQ 但是轉念一想,woc,每個點不一定只經過一次咯。 woc,那不就是三進位

hdu3001Travelling (狀態壓縮DP,)

Travelling Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3611 Accepted Submission

C++ printf列印二進位制,,八,十六等(利用itoa)

printf是格式化輸出函式,它可以直接列印十進位制,八進位制,十六進位制,輸出控制符分別為%d, %o, %x, 但是它不存在二進位制,如果輸出二進位制可以呼叫stdlib.h裡面的itoa函式。

天平秤問題(

[問題描述]:  有一隻天平和N只砝碼,如何設計這N只砝碼,才能使這天平能夠連續秤出的重量最大?假設砝碼的最小單位為1克,秤物時物品放在天平的左邊,砝碼可以放在右邊也可以放在左邊,不管放在哪一邊只要天平能夠平衡就行,物品的重量應是右邊砝碼總重量減去左邊砝碼的重量。 輸入一個

小數 oj132

三進位制小數 釋出時間: 2017年5月25日 19:57   最後更新: 2017年5月26日 00:44   時間限制: 1000ms   記憶體限制: 128M 描述 你的任務呢,是將一

8和16建立字串

開始 #include <string> // 8進位制Oct(octonary) //10進位制Dec(decimal) //16進位制Hex(hexadecimal) int main() { //我想將一個16/8/10進位制的數字賦值給一個int

Barbells(

題意:給你一串b數字。一串p。左右槓鈴需要相等 然後記錄加過重量的槓鈴的重量。如題中所示。 然後對於一個p 可以加左邊 可以加右邊 或者不加三種情況。所以可以用三進位制來表示。 #include<bits/stdc++.h> using namespace s

與兩道趣味數學題

現在我們普遍使用十進位制進行數學運算,另一種常使用的進位制是二進位制,在計算機運算之中。日常生活中好像沒有三進位制的立足之處。1個季度是3個月,應是三進位制。交通訊號的紅綠黃的三種狀態可以表示0、1、2來描述,這似乎與三進位制沾上了邊,可是最近紅綠黃燈多變成了紅綠燈,三進制

zzuoj1081 小數

#include"stdio.h" #include"string.h" #include"stdlib.h" void solve(int p[]) { int i; if(p[10]>=

C語言程式,解決之間的轉化,超簡單,告別的問題!

1、首先,需要先明白printf()函式的輸出格式控制引數:                           %d:十進位制有符號整數                           %u:十進位制無符號整數                          

十六轉八的快捷方法——格式化輸入輸出

    最近刷題的時候遇到一個基礎題,就是將16進位制數轉為8進位制數。咋一看極其簡單,用二進位制做中介即可,簡單規劃了一下就開始動手了。 問題描述  給定n個十六進位制正整數,輸出它們對應的八進位制數。輸入格式  輸入的第一行為一個正整數n (1<=n<=10)。  接下來n行,每行一個由0~

十進位制轉變為八(解決)

#include<stdio.h> #include<stdlib.h> #define max 100 typedef struct{     int data[max];     int top; }Stack; void CreatStack(S

Redis中get值中文顯示為\xe4\xbd\xa0\xe5\xa5\xbd的16字串怎麼解決

場景: 在伺服器上redis-cli其他(線上)伺服器中redis值時,遇到了這個問題,百度一下,果然有前人採坑,果斷收錄一下_ 在啟動Redis客戶端如下加入引數輸入可解決: [[email protected] redis]# ./bin/redis-cli --raw