參考:
主要思想:列舉二叉樹+計算寬度
如果只有1個葉子,直接輸出寬度為0;否則,從第2個(一定有根節點-1)開始一層一層挨個列舉編號為num的節點的值,直到用完所有w。
計算寬度時,從最後乙個填入的節點往前計算以它為中心的左右的長度,左邊為負,右邊為正,一直算到根節點(num = 1),r[1]-l[1]就是整個二叉樹的寬度。
比如:
2號節點(-1)的左邊寬度為-2,右邊為+1。2號節點的子節點都是葉子(左右寬度都為0)所以簡單,1號節點就有點複雜了,還有考慮孩子節點。
1號節點的左寬度:0 +(-4) 和 -3+2 中較小的那個。
1號節點的右寬度:0 - 4 和 1+2 中較大的那個。
總結:l[i] = min( l[x]-l, l[y]+r );
r[i] = max( r[x]-l, r[y]+r );
其中x,y是 i 的左右孩子節點,l是 i 為中心的天平左臂長,r是右臂長。
#include #include #include #include using namespace std;
const int n = 1005;
int t[n]; // 二叉樹陣列
double l[n],r[n],val[n],w[n];
double ans,wide;
bool vis[15];
int t,s;
// 計算二叉樹寬度
void judge( int n )
else if( t[i] )
} double a = r[1] - l[1];
if( a-wide<1e-5 )
}//使用陣列t [1....num] 來模擬二叉樹 根據二叉樹的性質 如果parent = 節點 i 那麼left child = 2*i right child = 2*i+1
// num : 當前正在列舉的位置 sit: 當前還剩下多少葉子節點可以填寫 use: 當前還需要多少填寫的內容
// -1 表示 該節點為懸掛點 不可填寫內容但兒子可以填寫內容
//0 表示 該節點不填寫任何內容 也就是不表示出來 作為終止
//n 表示把第n個物體填寫在這個位置
void dfs( int num, int sit, int use )
//如果父節點不是木棍,它不能填,填下乙個
if( t[num/2]!=-1 )
else
} }} int main()
else
} return 0;
}
天平難題 UVa 1354
給出房間的寬度r和s個掛墜的重量wi,設計乙個盡量寬 但寬度不能超過房間寬度r 的天平,掛著所有掛墜。天平由一些長度為1的木棍組成。木棍的每一端要麼掛乙個掛墜,要麼掛另外乙個木棍。如下圖所示,設n和m分別是兩端的總重量,要讓天平平衡,必須滿足n a m b。掛墜的寬度忽略不計,且不同的子天平可以相互...
練習記錄uva1354
題目 一道暴力搜尋題目,第乙個要點 列舉天平就相當列舉二叉樹。另外要記錄不同集合可以擺出的二叉樹所有狀態 偏左值,偏右值 再往上推。剛開始沒做過多少暴力搜尋題,以為像回溯法一樣找到一棵二叉樹統計寬度,在統計下一顆,貌似不太好辦。考慮到資料不大,直接記錄所有狀態即可。include include i...
UVA 12166 天平性質 字元處理
這題思維難度很大,關鍵是總結這個性質。1.天平性質 某個秤砣重量為w,高度為h,如果要讓這個天平平衡並且以這個秤砣為基準,那麼整個天平的總重量為w 2 h 2.利用這個性質 題目要求秤砣數量改變最少,就是說盡量多的不改變秤砣重量,把總質量作為主鍵,統計總質量相同的秤砣個數,最後計算出數量最多的,就是...