import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Stack; /* プログラミングのお題スレ Part12 //mevius.5ch.net/test/read.cgi/tech/1538096947/830 830 名前:デフォルトの名無しさん[sage] 投稿日:2018/12/16(日) 13:54:15.20 ID:ob8ozoeg [お題] 来年と素数 今年も残りわずか、来年は2019年で平成31年。 1)"2019"の省略形の"19"について。 素数の和で19を作る、すべての素数配列を列挙せよ(できれば辞書順で)。 同じ素数を何個使ってもよいが、同じ素数同士は区別しない。 ・例えば対象が"11"だと以下の6つ {2, 2, 2, 2, 3} {2, 2, 2, 5} {2, 2, 7} {2, 3, 3, 3} {3, 3, 5} {11} 以下 2)3)4)は種類計のみ答える(明細は多いので略)。 2)来年の初まりは平成31年で、"31"について。 素数の和で31を作る、その種類はいくつか。条件は1)と同様。 3)素数の和で2019を作る、その種類はいくつか。条件は1)と同様。 4)2019と31を続けた数 201931(=2019*100+31)について。 素数の和で201931を作る、その種類はいくつか。 但し、使用していい素数は31以下の素数かつ、 同じ素数は最大2019個までしか使えない。同じ素数は区別しない。 ※ 3)4)は64bit整数を超えるので、下10桁だけの回答も可。 */ class Ideone { { solve(11); solve(19); solve(31); solve(2019); solve(201931, 31, 2019); } static void solve(int n) { solve(n, n, n); } static void solve(int n, int max, int num) { for (int p = 2; p <= max; p = nextPrime(p + 1)) { for (int i = n, j = p + p * num; i - j >= 0; i--) b[i] = b[i].subtract(b[i - j]); for (int i = p; i <= n; i++) b[i] = b[i].add(b[i - p]); } { List<String> list = new ArrayList<>(); search(n, 0, 2, 0, max, num, new Stack<>(), list); } } static void search(int n, int cur, int p, int pn, int max, int num, Stack<Integer> stack, List<String> list) { if (n == cur) { list.add(stack.toString()); return; } if (cur + p <= n && pn < num) { stack.push(p); search(n, cur + p, p, pn + 1, max, num, stack, list); stack.pop(); } p = nextPrime(p + 1); while (cur + p <= n && p <= max) { stack.push(p); search(n, cur + p, p, 1, max, num, stack, list); stack.pop(); p = nextPrime(p + 1); } } static int nextPrime(int p) { if (p < 2) return 2; p |= 1; for (int i = 3; i * i <= p; i += 2) { if (p % i == 0) { p += 2; // i = 3; // バグはここだ!(´・ω・`) i = 1; } } return p; } }
Standard input is empty
N=11 => 6 [2, 2, 2, 2, 3] [2, 2, 2, 5] [2, 2, 7] [2, 3, 3, 3] [3, 3, 5] [11] N=19 => 23 [2, 2, 2, 2, 2, 2, 2, 2, 3] [2, 2, 2, 2, 2, 2, 2, 5] [2, 2, 2, 2, 2, 2, 7] [2, 2, 2, 2, 2, 3, 3, 3] [2, 2, 2, 2, 3, 3, 5] [2, 2, 2, 2, 11] [2, 2, 2, 3, 3, 7] [2, 2, 2, 3, 5, 5] [2, 2, 2, 13] [2, 2, 3, 3, 3, 3, 3] [2, 2, 3, 5, 7] [2, 2, 5, 5, 5] [2, 3, 3, 3, 3, 5] [2, 3, 3, 11] [2, 3, 7, 7] [2, 5, 5, 7] [2, 17] [3, 3, 3, 3, 7] [3, 3, 3, 5, 5] [3, 3, 13] [3, 5, 11] [5, 7, 7] [19] N=31 => 111 N=2019 => 576202207044176168646563 N=201931 素数の最大値=31 同じ素数の最大個数=2019 => 13683621769893119094927207253137