1.問題
10未満の4つの正の整数を指定すると、4つの演算と括弧の加算、減算、乗算、および除算を使用して、これらの4つの数値を接続して式を取得できます。ここで問題となるのは、式の結果を24に等しくする方法があるかどうかです。
括弧の加算、減算、乗算と除算、および演算結果と優先順位は、通常の定義と一致しています(除算の定義は実数除算です)。
たとえば、5、5、5、1の場合、5 *(5 – 1/5)= 24であるため、24を取得できます。別の例として、1、1、4、2の場合、24を取得することはできません。
入力
入力データには複数のラインが含まれ、各ラインは4未満の10未満の正の整数を含む一連のテストデータを提供します。テストデータの最後のセットには、入力の終わりを示す4つのゼロが含まれており、このデータセットを処理する必要はありません。
アウトプット
テストデータのセットごとに1行を出力し、24を取得できる場合は「YES」を出力し、それ以外の場合は「NO」を出力します。
样例输入
5 5 5 1
1 1 4 2
0 0 0 0
样例输出
YES
NO
二、Solution
方法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");
}
}
}
複雑さの分析
- 時間の複雑さ: 、
- スペースの複雑さ: 、