[Backtracking] C034_openj_ count 24 (практически без изменений)

1. Проблема

Учитывая, что 4 натуральных числа меньше 10, вы можете использовать сложение, вычитание, умножение и деление 4 операций и скобок, чтобы соединить эти 4 числа, чтобы получить выражение. Вопрос теперь в том, есть ли способ сделать результат выражения равным 24.

Сложение, вычитание, умножение и деление, а также результаты операции и приоритет скобок соответствуют нашему обычному определению (определение деления здесь является реальным делением).

Например, для 5, 5, 5, 1 мы знаем, что 5 * (5 - 1/5) = 24, поэтому мы можем получить 24. В качестве другого примера, для 1, 1, 4, 2 мы никогда не сможем получить 24.

запись

Входные данные включают в себя несколько строк, каждая строка дает набор тестовых данных, в том числе 4 менее 10 положительных целых чисел. Последний набор тестовых данных включает в себя 4 нуля, указывающих конец ввода, и этот набор данных не требует обработки.

экспорт

Для каждого набора тестовых данных выведите строку, если вы можете получить 24, выведите «YES», в противном случае выведите «NO».

样例输入
5 5 5 1
1 1 4 2
0 0 0 0
样例输出
YES
NO

Во-вторых, решение

Способ 1: возвращение

  • Используйте оператор для исчерпания номера, затем вернитесь к предыдущей операции, выберите следующую операцию и повторите процесс.
  • Когда глубокий поиск завершен, состояние необходимо восстановить.
import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
	static boolean done;
	static double[] a;
	static double INF = -1e6 * 1.0;
	final static int N = 4;
	static double ops(double a, double b, double k) {
		if (k == 0)      return a + b;
		else if (k == 1) return a - b;
		else if (k == 2) return a * b;
		else             return a / b;
	}
	static void dfs(int x) {
		if (done)
			return;
		Arrays.sort(a);
		if (x == N-1) {
		    if (Math.abs(a[N-1] - 24) < 0.00001)
			    done = true;
			return;
		}
		double[] t = Arrays.copyOf(a, a.length);
		for (int i = x; i < N; i++)
		for (int j = x; j < N; j++) {
		    if (i == j)
		        continue;
			for (int k = 0; k < N; k++) {
				a[i] = ops(a[i], a[j], k);
				a[j] = INF;
				dfs(x+1);
				a = Arrays.copyOf(t, t.length);;
			}
		}
	}
    public static void main(String[] args) throws IOException {  
        Scanner sc = new Scanner(new BufferedInputStream(System.in));
        BufferedWriter w = new BufferedWriter(new OutputStreamWriter(System.out));
        
		while (true) {
		    a = new double[N];
			for (int i = 0; i < a.length; i++) {
				a[i] = sc.nextDouble();
			}
			if (a[0] == 0 && a[1] == 0 && a[2] == 0 && a[3] == 0)
				return;
			done = false;
			dfs(0);
			if (done)System.out.println("YES");
			else 	 System.out.println("NO");
		}
    }
}

Анализ сложности

  • Сложность времени: ( 2 4 ) O (2 ^ 4)
  • Пространственная сложность: O ( n ) O (n)
Опубликовано 714 оригинальных статей · Хвала 199 · 50 000+ просмотров

рекомендация

отblog.csdn.net/qq_43539599/article/details/105624332
рекомендация