codeforces gym-101673 Twenty Four, Again 24点,枚举表达式树过题
生活随笔
收集整理的這篇文章主要介紹了
codeforces gym-101673 Twenty Four, Again 24点,枚举表达式树过题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目
題目鏈接
題意
給出4個數字,讓你任意指定運算符(3個)、增加括號、交換數,問組成24點的代價最小是多少。
增加括號:代價為1。
交換數的順序:代價為2。
題解
方法就是暴力枚舉,我們可以先枚舉數的順序(4!4!種可能性),再枚舉運算符類型(4343種可能性),再枚舉表達式樹的結構(55種情況,計算可以使用卡特蘭數計算)。
然后在把枚舉的數的順序、運算符填入表達式樹中去。
至于填括號的操作,我們在一顆完整的表達式樹構造完成后,可以判斷?、/?、/節點下是否有直接有+、?+、?,有幾個+、?+、?就要增加幾對括號。
這樣的話費用就計算出來了,下面只需要按照后序遍歷計算表達式樹,判斷結果是否為24就可以了。
注意如果不能整除的話,要提前終止計算,返回當前情況不滿足。
在我寫這道題的時候,排列、排列的代價、表達式樹的結構種類我都手動計算出來了,所以在這道題里面,顯得比較暴力。
代碼
#include <iostream> #include <algorithm> using namespace std; int a[4],na[4]; int ps[][4] = {{0,1,2,3},{0,1,3,2},{0,2,1,3},{0,2,3,1},{0,3,1,2},{0,3,2,1},{1,0,2,3},{1,0,3,2},{1,2,0,3},{1,2,3,0},{1,3,0,2},{1,3,2,0},{2,0,1,3},{2,0,3,1},{2,1,0,3},{2,1,3,0},{2,3,0,1},{2,3,1,0},{3,0,1,2},{3,0,2,1},{3,1,0,2},{3,1,2,0},{3,2,0,1},{3,2,1,0}}; int cp[] = {0,1,1,2,2,3,1,2,2,3,3,4,2,3,3,4,4,5,3,4,4,5,5,6}; struct node{int num,lson,rson; }ns[100]; void init(){ns[1].lson=2;ns[1].rson=3;ns[2].lson=4;ns[2].rson=5;ns[3].lson=6;ns[3].rson=7;ns[8].lson=9;ns[8].rson=10;ns[9].lson=11;ns[9].rson=12;ns[11].lson=13;ns[11].rson=14;ns[15].lson=16;ns[15].rson=17;ns[16].lson=18;ns[16].rson=19;ns[19].lson=20;ns[19].rson=21;ns[22].lson=23;ns[22].rson=24;ns[24].lson=25;ns[24].rson=26;ns[25].lson=27;ns[25].rson=28;ns[29].lson=30;ns[29].rson=31;ns[31].lson=32;ns[31].rson=33;ns[33].lson=34;ns[33].rson=35; } void tree_fill(int rt,int i,int& idx,int& op){if(ns[rt].lson == 0 && ns[rt].rson == 0){ns[rt].num = a[ps[i][idx++]];return ;}tree_fill(ns[rt].lson,i,idx,op);ns[rt].num = -(op%4)*1000 - 1000;op /= 4;tree_fill(ns[rt].rson,i,idx,op); } int calc(int rt,int &cost){if(ns[rt].lson == 0 && ns[rt].rson == 0) return ns[rt].num;if(ns[rt].num == -3000 || ns[rt].num == -4000){if(ns[ns[rt].lson].num == -1000 || ns[ns[rt].lson].num == -2000) cost ++;if(ns[ns[rt].rson].num == -1000 || ns[ns[rt].rson].num == -2000) cost ++;}int l = calc(ns[rt].lson,cost);int r = calc(ns[rt].rson,cost);if(l == -1000 || r == -1000) return -1000;switch(ns[rt].num){case -1000:return l+r;case -2000:return l-r;case -3000:return l*r;case -4000:if(r == 0 || l % r != 0) return -1000;return l / r;} } int mi = 1000; int main(){init();cin>>a[0]>>a[1]>>a[2]>>a[3];for(int t = 0;t < 5;++t)for(int i = 0;i < 24;++i){for(int j = 0;j < 64;++j){int idx = 0,op = j,cost = 2*cp[i];tree_fill(t*7+1,i,idx,op);int res = calc(t*7+1,cost);if(res == 24) mi = min(mi,cost);}}if(mi == 1000) puts("impossible");else printf("%d\n",mi); }總結
以上是生活随笔為你收集整理的codeforces gym-101673 Twenty Four, Again 24点,枚举表达式树过题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 桌面电源方案推荐桌面式电源
- 下一篇: 洛谷-省选斗兽场-动态规划1