題目如下:你有足夠數量的天秤和砝碼。每個天秤有10磅。天秤的左右兩邊可以放砝碼,也可以放天秤。題目要求是,在給定的初始組合情況下,如何添加砝碼,讓整體保證平衡。輸入是一串數字,第一行是一個整數,代表當前初始狀態一共有多少個天秤,每個天秤都有一個序號接下來往下,每兩行分別代表一個天秤左右兩邊所包含的天秤序號和包含的砝碼重量每一組的格式如下:左半的砝碼重量 <天秤i,天秤j,...>右半的砝碼重量 <天秤k,天秤m,...>其中,<>表示數組輸入樣例如下:4 //4個天秤0 1 //0號天秤左邊放置著1號天秤0 2 //0號天秤右邊放置著2號天秤0 //1號天秤左邊啥都沒有0 3 //1號天秤右邊放置著3號天秤3 //2號天秤左邊有三磅重的砝碼0 //2號天秤右邊啥都沒有0 //3號天秤左邊啥都沒有0 //3號天秤右邊啥都沒有輸出,輸出N行。第i行代表第i個天秤的左右兩邊需要添加多少重量的砝碼輸出樣例如下:0: 0 141: 10 02: 0 33: 0 0大家可以試試看。當時給我的時間是1小時,當時做完這題就可以進入phone interview,可惜掛在了phone interview那- -。
2 回答

BIG陽
TA貢獻1859條經驗 獲得超6個贊
下面來簡單的說一下思想:
針對input來看,其實就是有一棵或多棵現成的樹,目的就是把每個節點的左右兩個分支配平。
由于子節點的配平會影響到父節點的配平,所以很自然的就想到了用遞歸的方法來解這個問題。
整個遞歸過程就是一個樹的后序遍歷過程。
調整了代碼縮進,加入必要注釋
package PhoneInterview;import java.io.BufferedReader;import java.io.File;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;public class Balance { // 每個天秤的屬性 public boolean balanced = false;// 判斷是否已經配平 public int nodeID;// 天秤id public Balance[] leftChild = null;// 左子樹的天秤數組 public Balance[] rightChild = null;// 右子樹的天秤數組 public int balanceWeight = 10;// 自身重量 public int leftWeight = 0;// 左子樹總重量 public int rightWeight = 0;// 右子樹總重量 public int adding = 0;// 為了配平,還需添加多少重量的砝碼 // 遞歸函數 public static int balancing(Balance node) { // 判斷天秤左邊是否有子天秤 if (node.leftChild != null) { for (int i = 0; i < node.leftChild.length; i++) node.leftWeight += balancing(node.leftChild[i]); } // 判斷天秤右邊是否有紫天秤 if (node.rightChild != null) { for (int i = 0; i < node.rightChild.length; i++) { node.rightWeight += balancing(node.rightChild[i]); } } // 天秤左右子樹都計算完畢,來計算當前天秤左右重量差 node.adding = Math.abs(node.leftWeight - node.rightWeight); // 標記該天秤已經配平 node.balanced = true; return node.balanceWeight + node.leftWeight + node.rightWeight + node.adding; } // 主函數 public static void main(String[] args) { int N = 0; Balance[] Balances; BufferedReader br; try { // 載入數據,初始化過程,無視這個file name吧 br = new BufferedReader(new FileReader("input00.txt")); // load第一行,得到天秤總數 String string = br.readLine(); N = Integer.parseInt(string); // 初始化Balances數組 Balances = new Balance[N]; int i = 0; for (int k = 0; k < N; k++) { Balances[k] = new Balance(); Balances[k].nodeID = k; } /* * 開始一行一行的讀入數據,每兩行一個循環 */ while ((string = br.readLine()) != null) { // 天秤左半部分初始化 String[] strs = string.split(" "); Balances[i].leftWeight = Integer.parseInt(strs[0]); /* * 這里是根據數據格式來的 如果length超過1,那就代表除了自重的值以外 還有放置的子天秤 * 遂初始化子樹上的數組,添加對子天平的引用,方便日后調用 */ if (strs.length != 1) Balances[i].leftChild = new Balance[strs.length - 1]; for (int j = 1; j < strs.length; j++) { Balances[i].leftChild[j - 1] = Balances[Integer .parseInt(strs[j])]; } // 天秤右半部分初始化 string = br.readLine(); String[] strs1 = string.split(" "); Balances[i].rightWeight = Integer.parseInt(strs1[0]); // 同理左半部分的操作 if (strs1.length != 1) Balances[i].rightChild = new Balance[strs1.length - 1]; for (int j = 1; j < strs1.length; j++) { Balances[i].rightChild[j - 1] = Balances[Integer .parseInt(strs1[j])]; } i++; } // 初始化完畢,開始配平 for (i = 0; i < Balances.length; i++) { if (!Balances[i].balanced) Balance.balancing(Balances[i]); } // 輸出結果 for (int m = 0; m < Balances.length; m++) { if (Balances[m].leftWeight < Balances[m].rightWeight) System.out.println(m + ": " + Balances[m].adding + " 0"); else if (Balances[m].leftWeight >= Balances[m].rightWeight) System.out.println(m + ": 0 " + Balances[m].adding); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

倚天杖
TA貢獻1828條經驗 獲得超3個贊
個人解法如下:
假設天平之間沒有嵌套關系(即不會出現1在2左邊,2在1左邊這種情況)
為了使一個天平平衡,首先得把放在其左邊或右邊的天平配平
假設力矩為0,天平左右兩邊重量不等時在少的一邊用砝碼補上重量
如果符合以上,題目綜合性不錯,涉及了簡單樹的遍歷以及貪心算法
下面是代碼(腦袋不好使狀態,不知道弄對了沒——反正代碼風格成渣渣了)
import sys def set_balance(id): if not balanced[id]: for i in lcld[id]: lw[id] += set_balance(i) for i in rcld[id]: rw[id] += set_balance(i) if lw[id] < rw[id]: ladd[id] = rw[id] - lw[id] lw[id] += ladd[id] elif lw[id] > rw[id]: radd[id] = lw[id] - rw[id] rw[id] += radd[id] balanced[id] = True return lw[id] + rw[id]n = int(sys.stdin.readline()) lw = [5 for i in range(n)]rw = [5 for i in range(n)]lcld = [[] for i in range(n)]rcld = [[] for i in range(n)]for i in range(n): row = [int(v) for v in sys.stdin.readline().split()] lw[i] += row[0] for v in row[1:]: lcld[i].append(v) row = [int(v) for v in sys.stdin.readline().split()] rw[i] += row[0] for v in row[1:]: rcld[i].append(v) balanced = [False for i in range(n)]ladd = [0 for i in range(n)]radd = [0 for i in range(n)]for i in range(n): get_balance(i) for i in xrange(n): print "%d:%d %d" % (i, ladd[i], radd[i])
添加回答
舉報
0/150
提交
取消