Problem:
四つ子素数

(a, a+2, a+6, a+8) のように並んだ 4 つの素数の組を四つ子素数といいます。四つ子素数を構成する四つの素数のうち、最大の数をその四つ子素数の大きさと呼びます。例えば、最も小さい大きさの四つ子素数は、(5, 7, 11, 13) の組であり、その大きさは 13 です。次に大きい四つ子素数は、(11, 13, 17, 19) の組で、その大きさは 19 です。

整数 n (13 ≤ n ≤ 10,000,000) を入力とし、大きさが n 以下になるような四つ子素数のうち、最大となるものの大きさを出力するプログラムを作成してください。

Input

複数のデータセットの並びが入力として与えられます。入力の終わりはゼロひとつの行で示されます。
各データセットとして１つの整数 n が１行に与えられます。

データセットの数は 2000 を超えません。

Output

入力データセットごとに、最大となる四つ子素数の大きさを1行に出力します。

Sample Input

13
14
15
16
17
18
19
20
10000
0

Output for the Sample Input

13
13
13
13
13
13
19
19
9439

Solution in JAVA (judge verdict: Accepted)


import java.util.*;
import static java.lang.Math.*;
import static java.util.Arrays.*;

public class Main {

	int INF = 1 << 28;
	final int N = 10000001;
	boolean prime[];
	LinkedList<Integer> maxp;
	int[] p4;
	
	void run() {
		Scanner sc = new Scanner(System.in);
		prime = new boolean[N];
		maxp = new LinkedList<Integer>();
		prime();
		for(;;) {
			int val = sc.nextInt();
			if(val == 0) break;
			int l = 0; int r = p4.length-1;
			while(l<=r) {
				int c = (l + r) / 2;
				if( p4[c] < val ) l = c+1;
				else if(p4[c] > val) r = c-1;
				else {
					l = c;
					break;
				}
			}
//			debug(p4);
			if(l>p4.length-1)System.out.println(p4[r]);
			else if(r<0) System.out.println(p4[l]);
			else System.out.println(min(p4[l],p4[r]));
		}
		
	}
	
	void prime() {
		prime[0] = prime[1] = true;
		for(int i=2;i<N;i++) if(!prime[i]){
			if(i-8>=0 && (!prime[i-8] && !prime[i-6] && !prime[i-2])) {
				maxp.add(i);
//				debug(i);
			}
			for(int j=i*2;j<N;j+=i) prime[j] = true;
		}
		p4 = new int[maxp.size()];
		int size = maxp.size();
		for(int i=0;i<size;i++) p4[i] = maxp.removeFirst();
		
	}

	public static void main(String[] args) {
		new Main().run();
	}

	void debug(Object... os) {
		System.err.println(Arrays.deepToString(os));
	}
}