// 骨架树变到下一骨架。所有骨架树的总数应该是catalan数C(2n,n)/(n+1) // 对传统24点,n=3,骨架树共有C(6,3)/4 = 5种 bool go_next_state(node* p) { if (!p) return false; // r_child^ if (go_next_state(p->r_child)) return true; // l_child^, r_child=0 if (go_next_state(p->l_child)) { node* r_child_new = initial_state(get_op_count(p->r_child)); delete (p->r_child); p->r_child = r_child_new; return true; } // l_child--=0 r_child++=0 int lcount = get_op_count(p->l_child); int rcount = get_op_count(p->r_child); if (lcount > 0) { node* l_child_new = initial_state(lcount-1); node* r_child_new = initial_state(rcount+1); delete (p->l_child); delete (p->r_child); p->l_child = l_child_new; p->r_child = r_child_new; return true; } return false; }
int get_op_count(int N) { int count = 987654321; int temp, n; if (N == 1) { return 0; } else if (N == 2 || N == 3) { return 1; } else if (N == 4 || N == 6 || N == 9) { return 2; } else if (N == 5 || N == 7 || N == 8) { return 3; } n = N; if (n % 3 == 0) { n /= 3; count = 1; count += get_op_count(n); } n = N; if (n > 3 && (n-1) % 3 == 0) { n--; n /= 3; temp = 2; temp += get_op_count(n); count = (count < temp ? count : temp); } n = N; if (n > 4 && (n-2) % 3 == 0) { n -= 2; n /= 3; temp = 3; temp += get_op_count(n); count = (count < temp ? count : temp); } n = N; if (n % 2 == 0) { n /= 2; temp = 1; temp += get_op_count(n); count = (count < temp ? count : temp); } n = N; if (N > 2 && (n-1) % 2 == 0) { n--; n /= 2; temp = 2; temp += get_op_count(n); count = (count < temp ? count : temp); } return count; }
int main(void) { int N; scanf("%d", &N); printf("%d\n", get_op_count(N)); return 0; }
// 在一个固定形状表达式树上进行搜索 void calc_on_exptree(node* exp, const wchar_t* bop, const uti_list_t& uop, double* nums, int num_count, double result, int rr_level) { // 首先得到所有结点的线性引用 int n = get_op_count(exp); node** op_nodes = new node*[n]; node** num_nodes = new node*[n+1]; node** tmp_opnodes = op_nodes; node** tmp_numnodes = num_nodes; get_node_ref(exp, &tmp_opnodes, &tmp_numnodes); std::sort(nums, nums + num_count); size_t oup_count = 1; for (uti_list_t::const_iterator it = uop.begin(); it != uop.end(); ++it) oup_count *= (it->at_ub+1); // 遍历所有操作符组合和操作数组合 int* op_w = new int[n](); int* uop_w = new int[2*n+1](); size_t boplen = wcslen(bop); int i; do { for (i = 0; i < n; i++) op_nodes[i]->op = bop[op_w[i]]; if (check_bone(exp, rr_level)) { do { // 为每个结点分uop for (i = 0; i < n*2 + 1; i++) { node* p = (i < n)? op_nodes[i] : num_nodes[i - n]; int pattern = uop_w[i]; p->translist.clear(); for (uti_list_t::const_iterator it = uop.begin(); it != uop.end(); ++it) { int c = pattern % (it->at_ub+1); pattern /= (it->at_ub+1); p->translist.append(c, it->op); } } if (check_bone2(exp, rr_level)) { iterate_num_permutation(exp, num_nodes, nums, num_count, result, rr_level); } } while (next_n_hex_number(uop_w, uop_w + 2*n + 1, oup_count)); } } while (next_n_hex_number(op_w, op_w + n, boplen)); delete [] op_w; delete [] op_nodes; delete [] num_nodes; }
// 包括自身 int get_op_count(const node* p) { if (!p || p->t == nt_num) return 0; return get_op_count(p->l_child) + get_op_count(p->r_child) + 1; }