"Algorithm Competition·Quickly 300 Questions" One question per day: "Make up twenty-four"

" Algorithm Competition: 300 Quick Questions " will be published in 2024 and is an auxiliary exercise book for "Algorithm Competition" .
All questions are placed in the self-built OJ New Online Judge .
Codes are given in three languages: C/C++, Java, and Python. The topics are mainly mid- to low-level topics and are suitable for entry-level and advanced students.


" Make up twenty-four ", link: http://oj.ecustacm.cn/problem.php?id=1793

Question description

[Problem Description] You are given n numbers. You need to add symbols +, -, and × to n-1 intervals, and calculate the result according to normal priority. Please output how many options there are. The calculation result is equal to 24.
[Input format] The first line is a positive integer n (2≤n≤10). The n positive integers in the second line represent the given n numbers, and the numbers do not exceed 50.
[Output format] Output a number to represent the answer.
【Input sample】

5
2 4 6 8 16

【Output sample】

2

answer

   If you try all possible combinations, how many combinations are there? When n=10 numbers at most, 9 symbols need to be added, a total of 3 9 = 19683 3^9=1968339=19683 combinations, not many.
  Use DFS to search all possible combinations. Since there are only 19683 situations, no pruning is required.
  The code uses dfs() to search for all combinations of symbols. For each combination, use check() to check whether the calculated result is equal to 24. Calculate multiplication first, then addition and subtraction. The code below uses a simple and straightforward simulation method. Process the multiplication in the expression first. When multiplying two numbers, store the calculation result at the back and zero at the front, and change the sign to the previous addition and subtraction, such as 3+4×5. Process the multiplication first and convert it to 3. +0+20.
  There are other ways to write check(), for example, first convert the expression (called an infix expression) into a reverse Polish expression, and then use the stack to calculate the reverse Polish expression. Because it is more cumbersome, the code is not given here.
[Key points]DFS.

C++ code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n, a[11];
int op[11];               //第i个间隔的符号 + - * = 0 1 2
int ans;
ll check(){
    
       //先计算*,再计算+-
    ll t[11] = {
    
    0}, t_op[11] = {
    
    0};
    for(int i=1; i<=n; i++)
        t[i] = a[i], t_op[i] = op[i];
    //先处理乘号:把乘积结果存入t[i+1]、t[i]设置为0、符号沿用前面的符号
    for(int i = 1; i < n; i++)
        if(t_op[i] == 2)
            t[i+1] *= t[i], t[i] = 0, t_op[i] = t_op[i-1];
    //最后加减
    ll sum = t[1];
    for(int i = 1; i < n; i++){
    
    
        if(t_op[i] == 0)  sum += t[i+1]; //加
        else sum -= t[i+1];              //减
    }
    return sum;
}
void dfs(int depth){
    
    
    if(depth == n){
    
    
        if(check() == 24)   ans++;
        return;
    }
    for(int i = 0; i <= 2; i++) {
    
       //继续添加下一个符号
        op[depth] = i;
        dfs(depth + 1);
    }
}
int main(){
    
    
    cin >> n;
    for(int i = 1; i <= n; i++)    cin >> a[i];
    dfs(1);
    cout<<ans<<endl;
    return 0;
}

Java code

import java.util.Scanner;
public class Main {
    
    
    static int n, a[] = new int[11], op[] = new int[11]; // 第i个间隔的符号 + - * = 0 1 2
    static int ans;
    public static void main(String[] args) {
    
    
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        for (int i = 1; i <= n; i++)   a[i] = in.nextInt();
        dfs(1);
        System.out.println(ans);
        in.close();
    }
    static long check() {
    
     // 先计算*,再计算+-
        long[] t = new long[11];
        int[] t_op = new int[11];
        for (int i = 1; i <= n; i++) {
    
    
            t[i] = a[i];
            t_op[i] = op[i];
        }
        // 先处理乘号:把乘积结果存入t[i+1]、t[i]设置为0、符号沿用前面的符号
        for (int i = 1; i < n; i++) {
    
    
            if (t_op[i] == 2) {
    
    
                t[i + 1] *= t[i];
                t[i] = 0;
                t_op[i] = t_op[i - 1];
            }
        }
        // 最后加减
        long sum = t[1];
        for (int i = 1; i < n; i++) {
    
    
            if (t_op[i] == 0) sum += t[i + 1]; // 加
            else              sum -= t[i + 1]; // 减
        }
        return sum;
    }
    static void dfs(int depth) {
    
    
        if (depth == n) {
    
    
            if (check() == 24)   ans++;
            return;
        }
        for (int i = 0; i <= 2; i++) {
    
     // 继续添加下一个符号
            op[depth] = i;
            dfs(depth + 1);
        }
    }
}

Python code

n = int(input())
a = [0]+list(map(int, input().split()))     #输入到a[1]-a[10]
op = [0] * 11                               # 第i个间隔的符号 + - * = 0 1 2
ans = 0
def check():# 先计算*,再计算+-
    t = [0] * 11
    t_op = [0] * 11
    for i in range(1, n+1):
        t[i] = a[i]
        t_op[i] = op[i]
    # 先处理乘号:把乘积结果存入t[i+1]、t[i]设置为0、符号沿用前面的符号
    for i in range(1, n):
        if t_op[i] == 2:
            t[i+1] *= t[i]
            t[i] = 0
            t_op[i] = t_op[i-1]
    # 最后加减
    sum = t[1]
    for i in range(1, n):
        if t_op[i] == 0: sum += t[i+1]  # 加
        else:            sum -= t[i+1]  # 减
    return sum
def dfs(depth):
    global ans
    if depth == n:
        if check() == 24:   ans += 1
        return
    for i in range(3):                  # 继续添加下一个符号
        op[depth] = i
        dfs(depth + 1)
dfs(1)
print(ans)

Guess you like

Origin blog.csdn.net/weixin_43914593/article/details/132456311