import java.awt.geom.Line2D;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Main {
    final double pi = (1 << 2)
            * (Math.cbrt(1. / 0.015625) * Math.atan(0.2) - Math.atan(1. / 239));
    final double EPS = 1.0e-10;

    void run() {
        Scanner sc = new Scanner(System.in);
        while (true) {
            int n = sc.nextInt();
            if (n == 0)
                break;
            while (n != 0) {
                int m = sc.nextInt();
                Tetragon[] rs = new Tetragon[m];
                for (int i = 0; i < m; i++) {
                    P[] ps = new P[4];
                    for (int j = 0; j < 4; j++)
                        ps[j] = new P(sc.nextInt(), sc.nextInt());
                    rs[i] = new Tetragon(ps);
                }
                UnionFind uf = new UnionFind(m);
                for (int i = 0; i < m; i++) {
                    for (int j = 0; j < m; j++) {
                        if (i == j)
                            continue;
                        if (rs[i].isTouch(rs[j]))
                            uf.unite(i, j);
                    }
                }
                Set<Integer> set = new HashSet<Integer>();
                for (int i = 0; i < m; i++) {
                    set.add(uf.find(i));
                }
                System.out.println(set.size());
                n--;
            }
        }
    }

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

}

class P {
    int x;
    int y;

    P(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public String toString() {
        return "(" + x + " , " + y + ")";
    }

    public P add(P p) {
        return new P(p.x + x, p.y + y);
    }

    public P sub(P p) {
        return new P(x - p.x, y - p.y);
    }

    public P mul(int k) {
        return new P(k * x, k * y);
    }

    public double abs() {
        return Math.sqrt(x * x + y * y);
    }

    public int abs2() {
        return x * x + y * y;
    }

    public int det(P p) {
        return x * p.y - y * p.x;
    }

    public P rot90() {
        return new P(-y, x);
    }

    boolean inTetragon(Tetragon t) {
        boolean right = true;
        boolean left = true;
        for (int i = 0; i < 4; i++) {
            int ep = this.sub(t.ps[i]).det(t.ps[(i + 1) % 4].sub(t.ps[i]));
            if (ep < 0)
                left = false;
            else if (ep > 0)
                right = false;
        }
        return right || left;
    }
}

class Tetragon {
    P ps[] = new P[4];

    Tetragon(P qs[]) {
        for (int i = 0; i < 4; i++) {
            ps[i] = qs[i];
        }
    }

    boolean isTouch(Tetragon t) {
        for (int i = 0; i < 4; i++) {
            if (ps[i].inTetragon(t))
                return true;
        }
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                int x1 = ps[i].x;
                int y1 = ps[i].y;
                int x2 = ps[(i + 1) % 4].x;
                int y2 = ps[(i + 1) % 4].y;
                int x3 = t.ps[j].x;
                int y3 = t.ps[j].y;
                int x4 = t.ps[(j + 1) % 4].x;
                int y4 = t.ps[(j + 1) % 4].y;
                int tc = (x1 - x2) * (y3 - y1) + (y1 - y2) * (x1 - x3);
                int td = (x1 - x2) * (y4 - y1) + (y1 - y2) * (x1 - x4);
                int ta = (x3 - x4) * (y1 - y3) + (y3 - y4) * (x3 - x1);
                int tb = (x3 - x4) * (y2 - y3) + (y3 - y4) * (x3 - x2);

                if (tc * td < 0 && ta * tb < 0)
                    return true;
            }
        }
        return false;
    }
}

class UnionFind {
    int par[];
    int rank[];

    UnionFind(int n) {
        par = new int[n];
        rank = new int[n];
        for (int i = 0; i < n; i++) {
            par[i] = i;
        }
    }

    int find(int x) {
        if (x == par[x])
            return x;
        else
            return par[x] = find(par[x]);
    }

    void unite(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y)
            return;
        if (rank[y] > rank[x])
            par[x] = y;
        else {
            par[y] = x;
            if (rank[x] == rank[y])
                rank[x]++;
        }
    }

    boolean same(int x, int y) {
        return find(x) == find(y);
    }
}

秋のイルミネーション

四角形が大好きな人が多く住む四角町では、四角形の電光板を組み合わせたイルミネーションで町中を彩るお祭りが開催されます。この電光板は電気を流すと発光し、発光している板に接している板も発光します。したがって、電光板を何枚使っても、すべてがひとかたまりに接していれば電源がひとつで済むという優れものです。

お祭り実行委員会では、四角形を組み合わせたデザインを町民から募集し多数のイルミネーションを作成します。各イルミネーションは、デザインを構成する四角形の配置によって必要となる電源の個数が変わるため、必要な電源の個数を把握する作業に大きな手間がかかります。そこで、あなたは四角形の配置を調べ、必要な電源の個数を計算するプログラムを作成して実行委員会を手助けすることにしました。

イルミネーションの個数、各イルミネーションを構成する四角形の情報を入力とし、イルミネーションごとに必要な電源の個数を出力するプログラムを作成してください。重なっていたり接していたりする四角形を 1 つのまとまりと考え、1 つのまとまりに対して電源の個数は 1 つと数えてください。

Input

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

N
M1
xa1 ya1 xb1 yb1 xc1 yc1 xd1 yd1
xa2 ya2 xb2 yb2 xc2 yc2 xd2 yd2
:
xaM1 yaM1 xbM1 ybM1 xcM1 ycM1 xdM1 ydM1
M2
:
:
MN
:
:

1 行目にイルミネーションの個数 N (1 ≤ N ≤ 100) が与えられます。続いて、N 個のイルミネーションの情報が与えられます。第 i のイルミネーションの情報として、イルミネーションを構成する四角形の個数 Mi (1 ≤ Mi ≤ 100) が１行に与えられます。続く Mi 行に j 個目の四角形の頂点 xaj, yaj, xbj, ybj, xcj, ycj, xdj, ydj (-1000 以上 1000 以下の整数) が与えられます。

入力される四角形の頂点座標は、時計回りの順に従って入力されます。ただし、入力データの四角形はすべて凸な四角形とします。

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

Output

入力データセットごとに、イルミネーションごとに必要な電源の個数を出力します。出力する電源の個数は各イルミネーションが入力された順番に従ってください。

Sample Input

3
1
0 0 0 1 1 1 1 0
2
0 0 0 1 1 1 1 0
100 100 100 200 200 200 200 100
2
0 0 0 100 100 100 100 0
10 10 10 20 20 20 20 10
2
1
30 40 40 50 40 20 20 10
1
30 40 40 50 40 20 20 10
0

Output for the Sample Input

1
2
1
1
1


import java.io.*;
import java.util.StringTokenizer;

class Main {
	public static void main(String args[]) {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String buf;

		try {
			while (!(buf = br.readLine()).equals("0")) {
				int n = Integer.parseInt(buf);
				for (int i=0;i<n;i++) {
					StringTokenizer st = new StringTokenizer(br.readLine());
					int pm = Integer.parseInt(st.nextToken());
					int pe = Integer.parseInt(st.nextToken());
					int pj = Integer.parseInt(st.nextToken());
					System.out.println(classify(pm,pe,pj));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String classify(int pm,int pe,int pj) {
		if (pm==100||pe==100||pj==100) return "A";
		if ((pm+pe)/2>=90) return "A";
		int ave = (pm+pe+pj)/3;
		if (ave>=80) return "A";
		if (ave>=70) return "B";
		if (ave>=50) {
			if (pm>=80||pe>=80) return "B";
		}
		return "C";
	}
}

Global OOD problem IDs are disjoint from train, validation, and in-distribution test problem IDs.

クラス分け

会津進学塾では、生徒が塾に入る際に実力テストを行ってクラス分けをします。テストは数学、英語、国語の 3 科目行い、生徒を A,B,C クラスにクラス分けします。A クラスのレベルが一番高く、順に低くなっていきます。

クラス分けの判断は以下の表に基づきます。

条件

クラス

100 点の科目がある

A

数学と英語の平均点が 90 点以上

A

3 科目の平均点が 80 点以上

A

3 科目の平均点が 70 点以上

B

3 科目の平均点が 50 点以上で数学か英語が 80 点以上

B

上の条件を満たさない

C

複数の条件を満たす場合は、よりレベルの高いクラスに分けられます。

生徒の人数 n (1 ≤ n ≤ 10000)、各生徒の数学の点数 pmi (0 ≤ pmi ≤ 100)、英語の点数 pei (0 ≤ pei ≤ 100)、国語の点数 pji (0 ≤ pji ≤ 100) を入力とし、各生徒のクラスA,B,C (半角英字) を出力するプログラムを作成してください。

Input

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

n
pm1 pe1 pj1
pm2 pe2 pj2
:
pmn pen pjn

入力はすべて整数で与えられます。データセットの数は 1000 を超えません。

Output

入力データセットごとに、各生徒のクラスを順番に出力します。

Sample Input

4
100 70 20
98 86 55
80 34 36
65 79 65
2
99 81 20
66 72 90
0

Output for the Sample Input

A
A
B
C
A
B

Submitted source-code file size, in bytes.

Execution CPU time reported by official Project CodeNet metadata, in milliseconds.

Peak memory usage reported by official Project CodeNet metadata, in kilobytes.


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;

public class Main {

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

	//カロリーを計算する
	private void calorieCounting() {

		BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); //標準入力

		while (true) {

			try {

				String inputStr = bufferedReader.readLine();
				int confectioneryNum = Integer.parseInt(inputStr); //お菓子の数

				if (confectioneryNum == 0) {
					break;
				}

				LinkedList<Integer> proteinList = new LinkedList<Integer>(); //タンパク質のリスト
				LinkedList<Integer> lipidList = new LinkedList<Integer>(); //脂質のリスト
				LinkedList<Integer> carbohydrateList = new LinkedList<Integer>(); //炭水化物のリスト
				LinkedList<Integer> kcalList = new LinkedList<Integer>(); //カロリーのリスト

				//お菓子の情報を入力
				for (int i = 0; i < confectioneryNum; i++) {
					String inputStr2 = bufferedReader.readLine();
					String[] confectioneryInformationStrs = inputStr2.split(" ");
					int protein = Integer.parseInt(confectioneryInformationStrs[1]);
					int lipid = Integer.parseInt(confectioneryInformationStrs[2]);
					int carbohydrate = Integer.parseInt(confectioneryInformationStrs[3]);
					int kcal = (4 * protein) + (9 * lipid) + (4 * carbohydrate);

					proteinList.add(protein);
					lipidList.add(lipid);
					carbohydrateList.add(carbohydrate);
					kcalList.add(kcal);
				}

				LinkedList<Integer> canEatConfectioneryList = new LinkedList<Integer>(); //食べてもいい菓子の番号を管理する
				int index = 1; //お菓子番号
				Person person = new Person(); //お菓子を食べる人の情報

				//各栄養素、カロリーの制限値を入力
				String inputStr3 = bufferedReader.readLine();
				String[] personStrs = inputStr3.split(" ");
				person.setProtein(Integer.parseInt(personStrs[0]));
				person.setLipid(Integer.parseInt(personStrs[1]));
				person.setCarbohydrate(Integer.parseInt(personStrs[2]));
				person.setKcal(Integer.parseInt(personStrs[3]));

				for (int i = 0; i < confectioneryNum; i++) {

					boolean eatFlag = false; //trueなら食べられるお菓子

					//食べられるお菓子かどうかを判定する
					if (proteinList.get(i) < person.getProtein() && lipidList.get(i) < person.getLipid() &&
						carbohydrateList.get(i) < person.getCarbohydrate() && kcalList.get(i) < person.getKcal()) {
						eatFlag = true;
					}

					if (eatFlag) {
						canEatConfectioneryList.add(index);
					}

					index++;
				}

				if (canEatConfectioneryList.size() == 0) {

					System.out.println("NA");

				} else {

					for (int num : canEatConfectioneryList) {
						System.out.println(num);
					}

				}

			} catch (IOException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
			}

		}
	}
}

class Person {

	int protein = 0; //タンパク質
	int lipid = 0; //脂質
	int carbohydrate = 0; //炭水化物
	int kcal = 0; //カロリー

	public int getProtein() {
		return protein;
	}

	public void setProtein(int protein) {
		this.protein = protein;
	}

	public int getLipid() {
		return lipid;
	}

	public void setLipid(int lipid) {
		this.lipid = lipid;
	}

	public int getCarbohydrate() {
		return carbohydrate;
	}

	public void setCarbohydrate(int carbohydrate) {
		this.carbohydrate = carbohydrate;
	}

	public int getKcal() {
		return kcal;
	}

	public void setKcal(int kcal) {
		this.kcal = kcal;
	}

}

カロリー計算

食べ物には3大栄養素と呼ばれる「たんぱく質」「脂質」「炭水化物」の３つの栄養素が含まれています。１g（グラム）あたりたんぱく質と炭水化物は 4 kcal（キロカロリー）、脂質は 9 kcal と計算されます。たとえば、下の表によると番号１のケーキにはタンパク質 7 g、脂質 14 g、炭水化物 47 g が含まれています。これをもとに含まれるカロリーを計算すると、4 × 7 + 9 × 14 + 4 × 47 = 342 kcal となります。その他も同様に計算されています。

番号

名前

たんぱく質(g)

脂質(g)

炭水化物(g)

カロリー(kcal)

1

ケーキ

7

14

47

342

2

ポテトチップス

5

35

55

555

3

どら焼き

6

3

59

287

4

プリン

6

5

15

129

分類の対象となるお菓子の個数 n と各お菓子の情報、制限の情報を入力とし、そのお菓子一つだけなら制限を超えることがない（食べてもよい）お菓子の一覧を出力するプログラムを作成してください。

お菓子の情報は、お菓子の番号 s、そのお菓子に含まれるたんぱく質の重量 p、脂質の重量 q、炭水化物の重量 r から構成されています。制限の情報には、含むことができる最大のたんぱく質の重量 P、脂質の重量 Q、炭水化物の重量 R、および摂取することができる最大のカロリー C からなっており、タンパク質、脂質、炭水化物、カロリーのいずれかの一つでも超えると制限違反となり、「食べてはいけないお菓子」と判断されます。

食べてもよいお菓子の一覧は、食べてもよいお菓子の番号を入力順に出力してください。なお、食べてもよいお菓子がなければ”NA”と出力してください。
上の表にある4個のお菓子について、P = 10, Q = 15, R = 50, C = 400 という制限の場合、ケーキとプリンはそれぞれの栄養素及びカロリーが制限値以下なので食べてもよいお菓子に分類されますが、ポテトチップスは炭水化物とカロリー、どら焼きは炭水化物の量が制限値を超えているため食べてはいけないお菓子に分類されます。

入力

複数のデータセットの並びが与えられます。入力の終わりはゼロひとつの行で示されます。各データセットは以下の形式で与えられます。

n
s1 p1 q1 r1
s2 p2 q2 r2
:
sn pn qn rn
P Q R C

1行目にお菓子の数 n (1 ≤ n ≤ 1000)が与えられます。続く n 行に第 i のお菓子の番号 si (1 ≤ si ≤ 1000)、各栄養素の重量を表す整数 pi, qi, ri (0 ≤ pi, qi, ri ≤ 100) が与えられます。

続く行に各栄養素及びカロリーの制限値を表す整数 P, Q, R (0 ≤ P, Q, R ≤ 100), C (0 ≤ C ≤ 1700) が与えられます。

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

出力

データセットごとに、食べてもよいお菓子の番号または ”NA” を出力します。

入力例

4
1 7 14 47
2 5 35 55
3 6 3 59
4 6 5 15
10 15 50 400
2
1 8 10 78
2 4 18 33
10 10 50 300
0

出力例

1
4
NA


import java.util.Arrays;
import java.util.Scanner;

public class Main {
	static Scanner sc = new Scanner(System.in);
	static char[] N = new char[4];
	static int L,S;
	public static void main(String[] args){
		while(read()){
			solve();
		}
	}

	public static boolean read(){
		String tmp;
		tmp = sc.next();
		if(tmp.equals("0000")) return false;
		N = tmp.toCharArray();

		return true;

	}

	public static void solve(){

		int Nint = Integer.parseInt(String.valueOf(N));
		int ans = 0;

		while(Nint != 6174){
			Arrays.sort(N);
			S = Integer.parseInt(String.valueOf(N));
			L = ((int)N[3]-48) * 1000 + ((int)N[2]-48) * 100 + ((int)N[1]-48) * 10 + ((int)N[0]-48);

			Nint = L-S;
			if(Nint == 0) {
				System.out.println("NA"); return;
			}

			N = String.format("%04d", Nint).toCharArray();
			ans++;
		}

		System.out.println(ans);

		return;
	}
}

すべての数は６１７４に通ず

0 から 9 の数字からなる四桁の数 N に対して以下の操作を行う。

N の桁それぞれの数値を大きい順に並べた結果得た数を L とする

N の桁それぞれの数値を小さい順に並べた結果得た数を S とする

差 L-S を新しい N とする(1回分の操作終了)

新しい N に対して 1. から繰り返す

このとき、全桁が同じ数字(0000, 1111など)である場合を除き、あらゆる四桁の数はいつかは 6174になることが知られている。例えば N = 2012の場合

       1回目 (N = 2012): L = 2210, S = 0122, L-S = 2088

       2回目 (N = 2088): L = 8820, S = 0288, L-S = 8532

       3回目 (N = 8532): L = 8532, S = 2358, L-S = 6174

となり、3 回の操作で 6174 に到達する。

0 から 9 の数字からなる四桁の数が与えられたとき、何回の操作で 6174 に到達するか計算するプログラムを作成して下さい。

入力

入力は複数のデータセットからなる。入力の終わりは 0000 が１つの行で示される。各データセットは以下の形式で与えられる。

N

データセットは１行であり、N (1 ≤ N ≤ 9999) は四桁の数を示す。N < 1000 の場合は上の桁は 0 で埋められている。

データセットの数は 10000 を超えない。

出力

各データセットごとに何回の操作で 6174 に到達したかを１行に出力する。ただし全桁が同じ数字である数が入力として与えられた場合は NA と出力する。

入力例

6174
2012
3333
0000

出力例

0
3
NA


import java.util.Arrays;
import java.util.Scanner;

public class Main {
	static boolean[] isDist;
	static int N;
	static int M;
	static int p;
	public static int INF = 1 << 24;
	public static void main(String[] args) {
		Scanner stdIn = new Scanner(System.in);
		N = stdIn.nextInt();
		M = stdIn.nextInt();
		p = stdIn.nextInt();
		Limit = N*50;
		isDist = new boolean[N];
		for(int i = 0; i < M ;i++) {
			int d = stdIn.nextInt();
			isDist[d] = true;
		}
		boolean[] isDist2 = Arrays.copyOf(isDist,N);

		solv(1,p,0,0,false,isDist);
		solv(-1,p,0,0,false,isDist2);
		System.out.println(min);

	}
	static int min = 1 << 24;
	static int Limit;
	public static void solv(int vec, int now, int coun, int cos, boolean alC,boolean[] isDist) {

		int nowp = now;
		int cost = cos;
		int count = coun;
		while(true) {
			if(min <= cost)return;
			if(nowp == N) nowp = 0;
			else if(nowp == -1) nowp = N-1;
			if(count == M ) {
				if(min > cost)min = cost;
				return;
			}
			if(isDist[nowp]) {

				isDist[nowp] = false;
				count++;
				if(!alC && cost < Limit) {
					boolean[] isDist2 = Arrays.copyOf(isDist, N);

					solv(vec*-1,nowp+vec*-1,count,cost+100,true,isDist2);
				}
			}
			if(count == M ) {
				if(min > cost)min = cost;
				return;
			}
			while(true) {
				if(nowp == N) nowp = 0;
				else if(nowp == -1) nowp = N-1;
				if(!isDist[nowp]) {
					nowp += vec;
					cost += 100;
				}
				else {
					break;
				}
			}
		}
	}
}

鉄道路線II

わたしの住む街には、図のような N 個の駅からなる円環状の鉄道路線があります。この路線の各駅には 0 から N-1 までの番号が順番に割り当てられていて、隣の駅まで100 円で移動することができます。移動はどちらの方向にでも可能です。

わたしはこの路線上のいくつかの駅で買い物をしたいと思っています。そこで、プログラムを作成して移動費を計算することにしました。ある駅を始点として、買い物をするすべての駅を訪問する最小の費用（円）を求めるプログラムを作成してください。ただし、同じ駅を何度訪問しても良く、どのような順番で駅を訪問しても構いません。

入力

入力は以下の形式で与えられる。

N M p
d1
d2
:
dM

1行目に駅の数 N (2 ≤ N ≤ 100000)、買い物をする駅の数 M (1 ≤ M ≤ 10000 かつ M < N)、出発する駅の番号 p (0 ≤ p ≤ N-1) が与えられる。続く M 行に買い物をする駅の番号 di (0 ≤ di ≤ N-1) が与えられる。ただし、diは全て異なり、p もまたどの di とも異なるものとする。

出力

最小の費用を１行に出力する。

入出力例

入力例１

5 4 0
1
2
3
4

出力例１

400

入力例２

7 2 1
6
2

出力例２

400


import java.util.Scanner;

class Main {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int e[] = new int[13];
        int i;
        int p = 0;
        int k;
        for (i = 0; i < 12; i++) {
            e[i] = scan.nextInt();
        }
        for (i = 0; i < 12; i++) {
            for (int j = 0; j < 12 - i; j++) {
                if (e[j] < e[j + 1]) {
                    int y = e[j];
                    e[j] = e[j + 1];
                    e[j + 1] = y;

                }
            }
        }
        for (int u = 0; u < 3; u++) {
            for (k = 0; k < 4; k++) {
                i = u * 4;
                if (e[i] == e[i + 1] && e[i + 2] == e[i + 3] && e[i] == e[i + 2] && e[i + 1] == e[i + 3] && e[i] == e[i + 3] && e[i + 1] == e[i + 2]) {
                    p += 1;
                } else {
                    p += 0;
                }

            }

        }
        if (p == 12) {
            System.out.println("yes");
        } else {
            System.out.println("no");
        }
    }
}

MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

棒で作る直方体

アイヅ放送協会の教育番組(ＡＨＫ教育)では、子ども向けの工作番組「あそんでつくろ」を放送しています。今回は棒で箱を作る回ですが、用意した１２本の棒を使って直方体ができるかを確かめたいと思います。ただし、棒は切ったり折ったりしてはいけません。

１２本の棒の長さが与えられるので、それらすべてを辺とする直方体が作れるかどうか判定するプログラムを作成せよ。

Input

入力は以下の形式で与えられる。

e1 e2 ... e12

入力は１行からなり、各棒の長さを表す整数 ei (1 ≤ ei ≤ 100) が与えられる。

Output

直方体を作成できる場合には「yes」を、作成できない場合には「no」を出力する。ただし、立方体は直方体の一種なので、立方体の場合でも「yes」と出力する。

Sample Input 1

1 1 3 4 8 9 7 3 4 5 5 5

Sample Output 1

no

Sample Input 2

1 1 2 2 3 1 2 3 3 3 1 2

Sample Output 2

yes


import java.util.*;

public class Main {
	public static void main (String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		boolean[] isRights = new boolean[n];
		for (int i = 0; i < n; i++) {
		    isRights[i] = (sc.nextInt() == 0);
		}
		PriorityQueue<Integer> rights = new PriorityQueue<>();
		PriorityQueue<Integer> lefts = new PriorityQueue<>();
		for (int i = 0; i < n; i++) {
		    if (isRights[i]) {
		        rights.add(sc.nextInt());
		    } else {
		        lefts.add(sc.nextInt());
		    }
		}
		if (rights.size() == 0 || lefts.size() == 0) {
		    System.out.println(0);
		} else {
		    System.out.println(rights.peek() + lefts.peek());
		}
	}
}

Round Table of Sages

$N$ sages are sitting around a round table with $N$ seats. Each sage holds chopsticks with his dominant hand to eat his dinner. The following happens in this situation.

If sage $i$ is right-handed and a left-handed sage sits on his right, a level of frustration $w_i$ occurs to him. A right-handed sage on his right does not cause such frustration at all.

If sage $i$ is left-handed and a right-handed sage sits on his left, a level of frustration $w_i$ occurs to him. A left-handed sage on his left does not cause such frustration at all.

You wish you could minimize the total amount of frustration by clever sitting order arrangement.

Given the number of sages with his dominant hand information, make a program to evaluate the minimum frustration achievable.

Input

The input is given in the following format.

$N$
$a_1$ $a_2$ $...$ $a_N$
$w_1$ $w_2$ $...$ $w_N$

The first line provides the number of sages $N$ ($3 \leq N \leq 10$). The second line provides an array of integers $a_i$ (0 or 1) which indicate if the $i$-th sage is right-handed (0) or left-handed (1). The third line provides an array of integers $w_i$ ($1 \leq w_i \leq 1000$) which indicate the level of frustration the $i$-th sage bears.

Output

Output the minimum total frustration the sages bear.

Sample Input 1

5
1 0 0 1 0
2 3 5 1 2

Sample Output 1

3

Sample Input 2

3
0 0 0
1 2 3

Sample Output 2

0


import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;

public class Main{
	public static void main(String args[]) {
		Scanner scanner = new Scanner(System.in);
		int n;
		while((n=scanner.nextInt())>0){
			int a=0,b=0;
			for(int i=0;i<n;i++){
				int aa=scanner.nextInt(),bb=scanner.nextInt();
				if(aa>bb)a+=aa+bb;
				else if(aa<bb)b+=aa+bb;
				else {a+=aa;b+=bb;}
			}
			System.out.println(a + " "+b);
		}
	}
}

A と B の 2 人のプレーヤーが， 0 から 9 までの数字が書かれたカードを使ってゲームを行う．最初に， 2 人は与えられた n 枚ずつのカードを，裏向きにして横一列に並べる．その後， 2 人は各自の左から 1 枚ずつカードを表向きにしていき，書かれた数字が大きい方のカードの持ち主が，その 2 枚のカードを取る．このとき，その 2 枚のカードに書かれた数字の合計が，カードを取ったプレーヤーの得点となるものとする．ただし，開いた 2 枚のカードに同じ数字が書かれているときには，引き分けとし，各プレーヤーが自分のカードを 1 枚ずつ取るものとする．

例えば， A，B の持ち札が，以下の入力例 1 から 3 のように並べられている場合を考えよう．ただし，入力ファイルは n + 1 行からなり， 1 行目には各プレーヤのカード枚数 n が書かれており， i + 1 行目（i = 1，2，... ，n）には A の左から i 枚目のカードの数字と B の左から i 枚目の カードの数字が，空白を区切り文字としてこの順で書かれている．すなわち，入力ファイルの 2 行目以降は，左側の列が A のカードの並びを，右側の列が B のカードの並びを，それぞれ表している．このとき，ゲーム終了後の A と B の得点は，それぞれ，対応する出力例に示したものとなる．

　入力ファイルに対応するゲームが終了したときの A の得点と B の得点を，この順に空白を区切り文字として 1 行に出力するプログラムを作成しなさい．ただし， n ≤ 10000 とする．

入力例１

入力例２

入力例３

3

3

3

9 1

9 1

9 1

5 4

5 4

5 5

0 8

1 0

1 8

出力例１

出力例２

出力例３

19 8

20 0

15 14

入力

入力は複数のデータセットからなる．n が 0 のとき入力が終了する．データセットの数は 5 を超えない．

出力

データセットごとに、A の得点と B の得点を１行に出力する．

入力例

3
9 1
5 4
0 8
3
9 1
5 4
1 0
3
9 1
5 5
1 8
0

出力例

19 8
20 0
15 14

各データセットの出力の後（Bの得点の後）に改行を入れること。

上記問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。


import java.util.Scanner;

public class Main {
  public static void main(String[] args){
    new Main();
  }
  public Main(){
    Scanner sc = new Scanner(System.in);
    while(true){
      int w = sc.nextInt();
      int h = sc.nextInt();
      if(h==0 && w==0)break;
      int[][] dp = new int[h][w];
      dp[0][0] = 1;
      int n = sc.nextInt();
      while(n-->0){
        int x = sc.nextInt();
        int y = sc.nextInt();
        dp[y-1][x-1] = -1;
      }
      for(int i=0;i<h;i++){
        for(int j=0;j<w;j++){
          if(dp[i][j]==-1)continue;
          if(i>0 && dp[i-1][j]!=-1) dp[i][j] += dp[i-1][j];
          if(j>0 && dp[i][j-1]!=-1) dp[i][j] += dp[i][j-1];
        }
      }
      System.out.println(dp[h-1][w-1]);
    }
  }
}

通学経路

問題

太郎君の住んでいるJOI市は，南北方向にまっすぐに伸びる a 本の道路と，東西方向にまっすぐに伸びる b 本の道路により，碁盤の目の形に区分けされている．

南北方向の a 本の道路には，西から順に 1, 2, ... , a の番号が付けられている．また，東西方向の b 本の道路には，南から順に 1, 2, ... , b の番号が付けられている．西から i 番目の南北方向の道路と，南から j 番目の東西方向の道路が交わる交差点を (i, j) で表す．

太郎君は，交差点 (1, 1) の近くに住んでおり，交差点 (a, b) の近くのJOI高校に自転車で通っている．自転車は道路に沿ってのみ移動することができる．太郎君は，通学時間を短くするため，東または北にのみ向かって移動して通学している．

現在， JOI市では， n 個の交差点 (x1, y1), (x2, y2), ... , (xn, yn) で工事を行っている．太郎君は工事中の交差点を通ることができない．

太郎君が交差点 (1, 1) から交差点 (a, b) まで，工事中の交差点を避けながら，東または北にのみ向かって移動して通学する方法は何通りあるだろうか．太郎君の通学経路の個数 m を求めるプログラムを作成せよ．

入力

入力は複数のデータセットからなる．各データセットは以下の形式で与えられる．入力はゼロを２つ含む行で終了する．

1行目には，空白を区切りとして2個の整数 a, b が書かれている．これは，南北方向の道路の本数と，東西方向の道路の本数を表す． a, b は 1 ≤ a, b ≤ 16 をみたす．

2行目には, 工事中の交差点の個数を表す整数 n が書かれている． n は 1 ≤ n ≤ 40 をみたす．

続く n 行 (3行目から n+2 行目) には，工事中の交差点の位置が書かれている． i+2 行目には空白で区切られた整数 xi, yi が書かれており，交差点 (xi, yi) が工事中であることを表す． xi, yi は 1 ≤ xi, yi ≤ 16 をみたす．

データセットの数は 5 を超えない．

出力

データセットごとに, 太郎君の通学経路の個数 m を1行に出力する．

入出力例

入力例

5 4
3
2 2
2 3
4 2
5 4
3
2 2
2 3
4 2
0 0

出力例

5
5

下図は a=5, b=4, n=3 で，工事中の交差点が (2,2), (2,3), (4,2) の場合を表している．

この場合，通学経路は m=5 通りある． 5通りの通学経路を全て図示すると，以下の通り．

上記問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Deque;

import static java.lang.Integer.parseInt;

/**
 * Shuffle
 * JOI 8th, Pre 5
 */
public class Main {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String line;
		String[] words;

		while ((line = br.readLine()) != null && !line.isEmpty()) {

			int n = parseInt(line);
			if (n == 0) break;

			int m = parseInt(br.readLine());

			words = br.readLine().split(" ");

			int p, q, r;
			p = parseInt(words[0]);
			q = parseInt(words[1]);
			r = parseInt(words[2]);

			//shuffle
			//ABC -> CBA
			Deque<int[]> ABC = new ArrayDeque<>();
			ABC.offer(new int[]{1, n});

			for (int i = 0; i < m; i++) {
				line = br.readLine();

				int x, y;
				x = parseInt(line.substring(0, line.indexOf(' ')));
				y = parseInt(line.substring(line.indexOf(' ') + 1));
				y -= x;

				Deque<int[]> A = head(ABC, x);
				Deque<int[]> B = head(ABC, y);

				//C+B+A
				for (int[] b : B) ABC.offer(b);
				for (int[] a : A) ABC.offer(a);
			}

			//solve
			int count = 0;
			p--;
			q -= p;

			head(ABC, p);
			ABC = head(ABC, q);

			for (int[] c : ABC) {
				if (c[1] <= r) {
					count += c[1] - c[0] + 1;
				} else if (c[0] <= r && r < c[1]) {
					count += r - c[0] + 1;
				}
			}

			System.out.println(count);

		}
	}

	static Deque<int[]> head(Deque<int[]> deque, int size) {

		Deque<int[]> head = new ArrayDeque<>();

		while (size > 0) {
			int _x = deque.peek()[1] - deque.peek()[0] + 1;
			if (size == _x) {
				head.offer(deque.poll());
				size = 0;
			} else if (size > _x) {
				head.offer(deque.poll());
				size -= _x;
			} else if (size < _x) {
				head.offer(new int[]{
						deque.peek()[0],
						deque.peek()[0] + size - 1
				});
				deque.peek()[0] = deque.peek()[0] + size;
				size = 0;
			}
		}

		return head;
	}
}

シャッフル

問題

1 から n までの番号が書かれた n 枚のカードがある．まず，一番上が番号 1 のカード，上から2枚目が番号 2 のカード，…，一番下が番号 n のカードとなるように順番に重ねて，カードの山を作る．

カードの山に対して，「シャッフル(x,y)」と呼ばれる次のような操作を行うことで，カードを並び替える（x, y は 1 ≤ x < y < n をみたす整数）．

シャッフル(x,y)

n 枚のカードを，一番上から x 枚目までのカードからなる山A， x+1 枚目から y 枚目のカードからなる山B， y+1 枚目から n 枚目のカードからなる山C の3つの山に分ける．そして，山Aの上に山Bを重ね，さらにその上に山Cを重ねる．

例えば，順番に並んでいる9枚のカードに対して「シャッフル(3,5)」を行うと， 9 枚のカードに書かれた番号は, 上から順番に 6, 7, 8, 9, 4, 5, 1, 2, 3 となる．

最初の山の状態から m 回のシャッフル「シャッフル(x1, y1)」「シャッフル(x2, y2)」 … 「シャッフル(xm, ym)」を順番に行った後のカードの山において，上から数えて p 枚目から q 枚目のカードの中に番号が r 以下のカードが何枚含まれているかを求めるプログラムを作成せよ．

入力

入力は複数のデータセットからなる．各データセットは以下の形式で与えられる．

入力は m+3 行からなる． 1 行目にはカードの枚数 n が書かれている（3 ≤ n ≤ 1000000000 = 109）． 2 行目にはシャッフルの回数を表す整数 m が書かれている（1 ≤ m ≤ 5000）． 3 行目には整数 p, q, r が書かれている（1 ≤ p ≤ q ≤ n, 1 ≤ r ≤ n）． i + 3 行目（1 ≤ i ≤ m）には2つの整数 xi, yi (1 ≤ xi < yi < n) が空白を区切りとして書かれている．

n が 0 のとき入力の終了を示す. データセットの数は 5 を超えない．

出力

データセットごとに, m 回のシャッフル後のカードの山において，上から数えて p 枚目から q 枚目のカードの中に含まれている番号が r 以下のカードの枚数を１行に出力せよ．

入出力例

入力例

9
1
3 7 4
3 5
12
3
3 8 5
3 8
2 5
6 10
0

出力例

2
3

1つ目の入力例の山に対して, 「シャッフル(3,5)」を行うと，カードは上から順番に 6, 7, 8, 9, 4, 5, 1, 2, 3 となる．上から数えて 3 枚目から 7 枚目に含まれる番号が 4 以下のカードは，番号 4 と番号 1 の 2 枚である．

また，2つ目の入力例の山に対して, 「シャッフル(3,8)」「シャッフル(2,5)」「シャッフル(6,10)」を順番に行うと，カードは上から順番に 9, 10, 3, 11, 12, 4, 5, 6, 7, 8, 1, 2 となる．上から数えて 3 枚目から 8 枚目に含まれる番号が 5 以下のカードは 3 枚である．

上記問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。


import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) throws IOException {

		new Main().run();
	}

	private void run() throws IOException {
		Scanner scanner = new Scanner(System.in);
		while (true) {
			m = scanner.nextInt();
			n = scanner.nextInt();
			if ((m | n) == 0)
				break;
			M = new HashMap<Integer, Integer>();
			h = 1;
			a = new int[n][m];
			Y = new int[24];
			X = new int[24];
			for (int i = 0; i < n; i++)
				for (int j = 0; j < m; j++) {
					int t = scanner.nextInt();
					if (t == 0) {
						a[i][j] = -1;
					} else if (t == 1) {
						Y[h] = i;
						X[h] = j;
						a[i][j] = h++;
					} else {
						Y[0] = i;
						X[0] = j;
						a[i][j] = 0;
					}
				}
			System.out.println(slove(0, 1));
		}
	}

	private int slove(int cur, int bit) {
		int k = cur << 24 | bit;
		if (M.containsKey(k))
			return M.get(k);
		int res = 0;
		for (int[] mo : move) {
			int y = Y[cur];
			int x = X[cur];
			while (true) {
				y += mo[0];
				x += mo[1];
				if (!isOK(y, x))
					break;
				if (a[y][x] == 0)
					if (Integer.bitCount(bit) == h) {
						return res + 1;
					}
				if (a[y][x] >= 1) {
					if ((bit >> a[y][x] & 1) == 1)
						continue;
					res += slove(a[y][x], bit | 1 << a[y][x]);
					break;
				}
			}
		}
		M.put(cur << 24 | bit, res);
		return res;
	}

	private boolean isOK(int y, int x) {
		if (0 <= y && y < n && 0 <= x && x < m)
			return true;
		return false;
	}

	int m, n, h;
	int[] Y, X;
	int[][] a;
	int[][] move = { { -1, 0 }, { 0, -1 }, { 0, 1 }, { 1, 0 } };
	Map<Integer, Integer> M;
}

方向音痴のトナカイ

問題

今年も JOI 町にサンタクロースが空からやってきた．JOI 町にある全ての家には子供がいるので，このサンタクロースは JOI 町の全ての家にプレゼントを配ってまわらなければならない．しかし，今年は連れているトナカイが少々方向音痴であり，また建物の上以外に降りることができないため，全ての家にプレゼントを配るためには少々道順を工夫しなければならないようだ．

JOI 町は東西南北に区画整理されており，各区画は家，教会，空き地のいずれかである．JOI 町には 1 つだけ教会がある．次のルールに従い，サンタクロースとトナカイは教会から出発し，全ての家に 1 回ずつプレゼントを配った後，教会に戻る．

今年のトナカイは少々方向音痴であるため，東西南北いずれかの方向にまっすぐ飛ぶことしかできず，空中では方向転換できない．

まだプレゼントを配っていない家の上は自由に通過できる．まだプレゼントを配っていない家には降りることができる．家に降りた時は必ずプレゼントを配り，その後は東西南北いずれかの方向に飛び立つ．

JOI 町の家では，クリスマスの夜はサンタクロースが来るまでは暖炉をつけずに過ごしているが，サンタクロースが飛び立った後は暖炉をつける．暖炉をつけると煙突から煙が出るので，プレゼントを配り終えた家の上を通過することはできない．

教会の上は自由に通過することができる．しかし，教会では礼拝が行われているので，全てのプレゼントを配り終えるまで教会に降りることはできない．

空き地の上は自由に通過することができるが，空き地に降りることはできない．

入力として町の構造が与えられたとき，サンタクロースとトナカイがプレゼントを配る道順が何通りあるかを求めるプログラムを作成せよ．

入力

入力は複数のデータセットからなる．各データセットは以下の形式で与えられる．

各データセットは n+1 行ある．
1 行目には整数 m (1 ≤ m ≤ 10) と整数 n (1 ≤ n ≤ 10) が空白で区切られて書かれている．
2 行目から n+1 行目までの各行には，0，1，2 のいずれかが，
空白で区切られて m 個書かれており，各々が各区画の状態を表している．
北から i 番目，西から j 番目の区画を (i,j) と記述することにすると
(1 ≤ i ≤ n, 1 ≤ j ≤ m)，
第 i+1 行目の j 番目の値は，
区画 (i,j) が空き地である場合は 0 となり，
家である場合は 1 となり，
教会である場合は 2 となる．
教会の個数は 1 であり，家の個数は 1 以上 23 以下である．
ただし，採点用入力データでは配る道順が 2000000 通りをこえることはない．

m, n がともに 0 のとき入力の終了を示す.データセットの数は 5 を超えない．

出力

データセットごとに,プレゼントを配る道順が何通りあるかを表す整数を1 行に出力する．

入出力例

入力例

3 2
1 0 1
1 0 2
3 3
1 1 1
1 0 1
1 1 2
0 0

出力例

2
6

図: 2つ目の入力例 に対する 6 通り全ての道順
（数字は配る順序を表す）

上記問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。


import java.util.Scanner;

public class Main
{
	public static void main(String[] args)
	{
		Scanner scan = new Scanner(System.in);

		while(scan.hasNext())
		{
			int N = scan.nextInt();
			int K = scan.nextInt();
			for(int i=0;i<K;i++)
			{
				int x = scan.nextInt()-1;
				int y = scan.nextInt()-1;

				if(x>N/2)
					x = N-1-x;
				if(y>N/2)
					y = N-1-y;
				int ans = Math.min(x,y);
				System.out.println(ans%3+1);
			}
		}
	}
}

タイル (Tile)

問題

JOI 高校では， 1 × 1 の正方形のタイルを使って N × N の正方形の壁画を作り，文化祭で展示することになった．タイルの色は，赤，青，黄の 3 種類である．壁画のデザインは次の通りである．まず，最も外側の周に赤のタイルを貼り，その内側の周に青のタイルを貼る．さらにその内側の周に黄色のタイルを貼る．これを N × N の正方形が埋め尽くされるまで繰り返す．用いるタイルの色は，一番外側の周から順番に赤，青，黄，赤，青，黄，…である．

文化祭が近づいてきたある日，壁画のうち K 枚のタイルがはがれていることが判明した．そこで，新しいタイルを購入して，はがれた箇所に新しいタイルを貼ることにした．

入力として壁画の一辺の長さ N と，はがれたタイルの枚数 K， K 枚のはがれたタイルの位置が与えられたとき，はがれたタイルの色を求めるプログラムを作成せよ．

例えば，N = 11 の場合，11 × 11 の壁画のデザインは下図の通りである．

また，N = 16 の場合，16 × 16 の壁画のデザインは下図の通りである．

入力

入力は全部で 2+K 行からなる． 1 行目には，壁画の一辺の長さ N （1 ≤ N ≤ 1000000000 = 109）が， 2 行目には，はがれたタイルの枚数 K （1 ≤ K ≤ 1000）が書かれている． 2+i 行目（1 ≤ i ≤ K）には，2 つの整数 ai と bi （1 ≤ ai ≤ N, 1 ≤ bi ≤ N）が空白区切りで書かれており， i 枚目のはがれたタイルが，左から ai 列目，上から bi 行目のタイルであることを表す．

入力の 3 行目から 2+K 行目には同じタイルを表す行が重複して現れることはない．また，与えられる入力データ 40% では， N ≤ 1000 をみたしている．

出力

出力は K 行からなる．各行は 1 つの整数からなり， i 行目（1 ≤ i ≤K）の整数は，i 枚目のはがれたタイルが赤のときは 1 を，青のときは 2 を，黄色のときは 3 を表す．

入出力例

入力例 1

11
4
5 2
9 7
4 4
3 9

出力例 1

2
3
1
3

入力例 2

16
7
3 7
5 2
11 6
15 2
9 7
8 12
15 16

出力例 2

3
2
3
2
1
2
1

問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。


import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int jAll = sc.nextInt();
        int mAll = sc.nextInt();
        int jEach = sc.nextInt();
        int mEach = sc.nextInt();
        System.out.println(n - Math.max((jAll + jEach - 1) / jEach, (mAll + mEach - 1) / mEach));
    }
}

宿題 (Homework)

問題

冬休みの宿題に毎回苦しめられてきた JOI 君が，今回は宿題を計画的に実行することにした．宿題は国語と算数のドリルであり，国語のドリルは A ページ，算数のドリルは B ページある．

JOI 君は，1 日に国語のドリルを最大 C ページと，算数のドリルを最大 D ページ進めることができるが，宿題をするとその日は遊ぶことができない．

冬休みは L 日あり，JOI 君は冬休み中に宿題を終わらせなければならない．JOI 君が冬休み中に最大で何日遊べるかを求めるプログラムを作成せよ．

入力

入力は 5 行からなり，1 行に 1 つずつ正の整数が書かれている．

1 行目には整数 L (2 ≦ L ≦ 40) が書かれており，冬休みの日数を表す．

2 行目には整数 A (1 ≦ A ≦ 1000) が書かれており，国語のドリルのページ数を表す．

3 行目には整数 B (1 ≦ B ≦ 1000) が書かれており，算数のドリルのページ数を表す．

4 行目には整数 C (1 ≦ C ≦ 100) が書かれており，JOI 君が 1 日に進めることができる国語のドリルの最大ページ数を表す．

5 行目には整数 D (1 ≦ D ≦ 100) が書かれており，JOI 君が 1 日に進めることができる算数のドリルの最大ページ数を表す．

ただし，与えられる入力データにおいては，JOI 君が冬休み中に宿題を必ず終わらせることができ，
少なくとも 1 日は遊べることが保証されている．

出力

JOI 君が冬休み中に遊べる日数の最大値を 1 行で出力せよ．

入出力例

入力例 1

20
25
30
6
8

出力例 1

15

入出力例 1 では，冬休みは 20 日間あり，国語のドリルが 25 ページ，算数のドリルが 30 ページある．JOI 君は 1 日に国語のドリルを最大 6 ページ，算数のドリルを最大 8 ページ進めることができる．例えば JOI 君が冬休み初日から国語のドリルを 6 ページ，算数のドリルを 8 ページずつ進めたとすると，国語のドリルを 5 日目に，算数のドリルを 4 日目に終わらせることができ，15 日間遊ぶことができる．これが JOI 君が冬休み中に遊べる日数の最大値なので，15 を出力する．

入力例 2

15
32
48
4
6

出力例 2

7

入出力例 2 では，
例えば JOI 君が初日から国語のドリルを 4 ページ，算数のドリルを 6 ページずつ進めたとすると，8 日目に両方のドリルを終わらせることができ，7 日間遊ぶことができる．これが JOI 君が冬休み中に遊べる日数の最大値なので，7 を出力する．

問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。


import java.lang.reflect.Array;
import java.util.*;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		LinkedList<Integer> a = new LinkedList<Integer>();
		for(int i=1;i<=n;i++){
			a.add(sc.nextInt());
		}
		Collections.sort(a);

		int ans = 0;
		String s = String.valueOf(a.pollFirst());
		String sss = String.valueOf(a.pollFirst());
		String ss = String.valueOf(a.pollFirst());
		if(n==3)
			ans = Integer.parseInt(sss+s);
		else
			ans = Integer.parseInt(s+ss);
		System.out.println(ans);

	}
}

問題 3

　入力ファイルの１行目に正整数 n （n≧3）が書いてあり，
つづく n 行に異なる正整数 a1, ..., an が
１つずつ書いてある．
a1, ..., an から異なる２個を選んで作られる
順列を（数として見て）小さい順に並べたとき，
３番目に来るものを出力せよ．

　ただし，
例えば，a1 = 1，a4 = 11 のような場合も，
a1a4 と a4a1 は異なる順列とみなす．
また，
1≦ai≦10000 (i=1, ..., n) かつ 3≦n≦104 である．

出力ファイルにおいては，
出力の最後にも改行コードを入れること．

入出力例

入力例１

3
2
7
5

出力例１

52

入力例２

4
17
888
1
71

出力例２

171

問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
	public static void main(String[] args)throws IOException{
		InputStreamReader isr = new InputStreamReader(System.in);
		BufferedReader reader = new BufferedReader(isr);
		String str, s[];

		int n, q, date[];
		x : while(!(str = reader.readLine()).equals("0 0")){
			s = str.split(" ");
			n = Integer.valueOf(s[0]);
			q = Integer.valueOf(s[1]);

			date = new int[110];
			for(int i = 0; i < n; i++){
				s = reader.readLine().split(" ");
				for(int j = 1; j <= Integer.valueOf(s[0]); j++){
					date[Integer.valueOf(s[j])]++;
				}
			}
			for(int i = n; i >= q; i--)
				for(int j = 1; j < date.length; j++){
					if(date[j] == i){
						System.out.println(j);
						continue x;
					}
				}
			System.out.println(0);
		}
		reader.close();
	}
}

When Can We Meet?

The ICPC committee would like to have its meeting as soon as
possible to address every little issue of the next contest.
However, members of the committee are so busy maniacally developing
(possibly useless) programs that it is very difficult to arrange
their schedules for the meeting.
So, in order to settle the meeting date, the chairperson requested every
member to send back a list of convenient dates by E-mail.
Your mission is to help the chairperson, who is now dedicated to other
issues of the contest, by writing a program that
chooses the best date from the submitted lists.
Your program should find the date convenient for the most members.
If there is more than one such day, the earliest is the best.

Input

The input has multiple data sets, each starting with a line
containing the number of committee members and the quorum of the meeting.

N Q

Here, N, meaning the size of the committee, and Q
meaning the quorum, are positive integers. N is less than 50,
and, of course, Q is less than or equal to N.

N lines follow, each describing convenient dates for a
committee
member in the following format.

M Date1
Date2 ... DateM

Here, M means the number of convenient dates for
the member, which is an integer greater than or equal to zero.
The remaining items in the line are his/her dates of convenience,
which are positive integers less than 100, that is, 1 means tomorrow,
2 means the day after tomorrow, and so on.
They are in ascending order without any repetition
and separated by a space character.
Lines have neither leading nor trailing spaces.

A line containing two zeros indicates the end of the input.

Output

For each data set, print a single line containing the date number
convenient for the largest number of committee members.
If there is more than one
such date, print the earliest. However, if no dates are convenient
for more than or equal to the quorum number of members, print 0 instead.

Sample Input

3 2
2 1 4
0
3 3 4 8
3 2
4 1 5 8 9
3 2 5 9
5 2 4 5 7 9
3 3
2 1 4
3 2 5 9
2 2 4
3 3
2 1 2
3 1 2 9
2 2 4
0 0

Output for the Sample Input

4
5
0
2


import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {

	static Scanner br = new Scanner(System.in);
	static List<Integer> tmp = new ArrayList<Integer>();

	public static void main(String[] args) throws IOException {
		int yamahuda[];

		while (true) {
			// ?±±???????????°n
			int n = br.nextInt();
			yamahuda = new int[n];
			// ??????????????°r
			int r = br.nextInt();

			// 0 0?????´???break;
			if (n == 0 && r == 0) {
				break;
			}

			// ?±±????????????n????????????
			for (int i = 0; i < n; i++) {
				yamahuda[i] = n - i;
			}
			// ?±±???????????£?????????
			for (int i = 0; i < r; i++) {
				shuffle(yamahuda);
			}
			System.out.println(yamahuda[0]);

		}
	}

	public static int[] shuffle(int[] yamahuda) throws IOException {
		// p??¨c?????\???
		int p = br.nextInt();
		int c = br.nextInt();
		tmp.clear();
		if (p - 1 < c) {

			// ?????????????±±???????????????????????????tmp???????´?
			for (int i = 0; i < c; i++) {
				tmp.add(yamahuda[p - 1 + i]);
			}
			for (int i = 0; i < p - 1; i++) {
				yamahuda[c + i] = yamahuda[i];
			}
			for (int i = 0; i < c; i++) {
				yamahuda[i] = tmp.get(i);
			}
		} else {
			// ???????????????
			for (int i = 0; i < p - 1; i++) {
				tmp.add(yamahuda[i]);
			}
			for (int i = 0; i < c; i++) {
				yamahuda[i] = yamahuda[p - 1 + i];
			}
			for (int i = 0; i < p - 1; i++) {
				yamahuda[c + i] = tmp.get(i);
			}
		}
		return yamahuda;
	}

}

Problem A: Hanafuda Shuffle

There are a number of ways to shuffle a deck of cards. Hanafuda
shuffling for Japanese card game 'Hanafuda' is one such example.
The following is how to perform Hanafuda shuffling.

There is a deck of n cards. Starting from the p-th card
from the top of the deck, c cards are pulled out
and put on the top of the deck, as shown in Figure 1.
This operation, called a cutting operation, is repeated.

Write a program that simulates Hanafuda shuffling and answers which
card will be finally placed on the top of the deck.

Figure 1: Cutting operation

Input

The input consists of multiple data sets.
Each data set starts with a line containing two positive integers n
(1 <= n <= 50) and r (1 <= r <= 50); n and
r are the number of cards in the deck and the number of cutting
operations, respectively.

There are r more lines in the data set, each of which
represents a cutting operation. These cutting operations
are performed in the listed order.
Each line contains two positive integers p and c
(p + c <= n + 1).
Starting from the p-th card from the top of the deck, c
cards should be pulled out and put on the top.

The end of the input is indicated by a line which contains two zeros.

Each input line contains exactly two integers separated by a space
character.
There are no other characters in the line.

Output

For each data set in the input, your program
should write the number of the top card after the shuffle.
Assume that at the beginning the cards
are numbered from 1 to n, from the bottom to the top.
Each number should be written in a separate line
without any superfluous characters such as leading or following spaces.

Sample Input

5 2
3 1
3 1
10 3
1 10
10 1
8 3
0 0

Output for the Sample Input

4
4


import java.util.*;

public class Main
{
	public static void main(String[] args)
	{
		try
		{
			int n, r, p, c, count;
			Scanner sc = new Scanner(System.in);
			String input;

			while(true)
			{
				n = sc.nextInt();
				r = sc.nextInt();

				int[] deck = new int[n];
				int[] ndeck = new int [n];

				for(int i = n; i > 0; i--)
				{
					deck[n - i] = i;
					ndeck[n - i] = deck[n - i];
				}

				if(n == 0 && r == 0)
				{
					break;
				}

				while(r > 0)
				{
					count = 0;
					p = sc.nextInt();
					c = sc.nextInt();

					for(int i = p - 1; i < p - 1 + c; i++)
					{
						ndeck[count] = deck[i];
						count++;
					}

					for(int i = 0; i < p - 1; i++)
					{
						ndeck[count] = deck[i];
						count++;
					}

					for(int i = 0; i < n; i++)
					{
						deck[i] = ndeck[i];
					}

					r--;
				}

				System.out.println(ndeck[0]);
			}

		}
		catch(InputMismatchException e)
		{
			System.out.println(e);
		}
	}
}


import java.util.*;

public class Main {
	public static void main(String args[]){
		Scanner in = new Scanner(System.in);
		while(true){
			int n = in.nextInt(), r = in.nextInt();
			if(n==0 && r==0) return ;
			int ps[] = new int[r], cs[] = new int[r];
			for(int i=r-1; i>=0; i--){
				ps[i] = in.nextInt();
				cs[i] = in.nextInt();
			}
			int pos = n;
			for(int i=0; i<r; i++){
				if(n-pos+1 <= cs[i]){
					pos -= ps[i] - 1;
				}
				else if(n-pos+1 < cs[i] + ps[i]){
					pos += cs[i];
				}
			}
			System.out.println(pos);
		}
	}
}


import java.io.BufferedReader;
import java.io.InputStreamReader;

class Main{
	static int points0[][];
	public static void main(String args[]){
		// 標準入力準備
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		//Scanner sc = new Scanner(System.in);
		//String str = new String();

		try{
			while(true){
				// 折れ線の数
				int n = Integer.parseInt(br.readLine());
				if(n == 0) return;

				// 最初のひとつ
				points0 = input(br);
				//printPoints(points0);

				//比較
				for(int i = 1; i <= n; i++){
					int pointsi[][] = input(br);
					//printPoints(points0);
					//if(compare(points0, pointsi)) System.out.println(i);
				}
				System.out.println("+++++");

			}

		}catch(Exception e){
			System.err.println(e);
		}
	}

	static boolean compare(int points1[][], int points2[][]){
		return compareAsce(points1, points2) ||  compareDsce(points1, points2);
	}

	static boolean compareAsce(int points1[][], int points2[][]){
		return compare0(points1, points2) || compare90(points1, points2) || compare180(points1, points2);
	}

	static boolean compareDsce(int points1[][], int points2[][]){
		// 逆向きにする
		int new_points2[][] = new int[points2.length][2];
		int originx = points2[points2.length - 1][0];
		int originy = points2[points2.length - 1][1];
		new_points2[0][0] = 0;
		new_points2[0][1] = 0;
		for(int i = 1; i < points2.length; i++){
			new_points2[i][0] = points2[points2.length - 1 - i][0] - originx;
			new_points2[i][1] = points2[points2.length - 1 - i][1] - originy;
		}
		return compareAsce(points1, new_points2);
	}

	static boolean compare0(int points1[][], int points2[][]){
		for(int i = 0; i < points1.length; i++){
			if(points1[i][0] != points2[i][0] || points1[i][1] != points2[i][1]) return false;
		}
		return true;
	}

	static boolean compare90(int points1[][], int points2[][]){
		for(int i = 0; i < points1.length; i++){
			if(points1[i][0] != points2[i][1] || points1[i][1] != 0 - points2[i][0]) return false;
		}
		return true;
	}

	static boolean compare180(int points1[][], int points2[][]){
		for(int i = 0; i < points1.length; i++){
			if(points1[i][0] != 0 - points2[i][0] || points1[i][1] != 0 - points2[i][1]) return false;
		}
		return true;
	}

	static boolean compare270(int points1[][], int points2[][]){
		for(int i = 0; i < points1.length; i++){
			if(points1[i][0] != 0 - points2[i][1] || points1[i][1] != points2[i][0]) return false;
		}
		return true;
	}

	static int[][] input(BufferedReader br) throws Exception{
		int m = Integer.parseInt(br.readLine());
		int points[][] = new int[m][2];

		// 原点を0に
		String strs[] = br.readLine().split(" ");
		int originx = Integer.parseInt(strs[0]);
		int originy = Integer.parseInt(strs[1]);
		//System.out.println("原点: (" + originx + ", " + originy + ")");
		points[0][0] = 0;
		points[0][1] = 0;

		for(int i = 1; i < m; i++){
			strs = br.readLine().split(" ");
			points[i][0] = Integer.parseInt(strs[0]) - originx;
			points[i][1] = Integer.parseInt(strs[1]) - originy;
		}
		return points;
	}

	static void printPoints(int points[][]){
		for(int i = 0; i < points.length; i++){
			System.out.print("(" + points[i][0] + ", " + points[i][1] + ")\t");
		}
		System.out.println();
	}
}

Problem B: Polygonal Line Search

Multiple polygonal lines are given on the xy-plane.
Given a list of polygonal lines and a template,
you must find out polygonal lines
which have the same shape as the template.

A polygonal line consists of several line segments parallel to x-axis or
y-axis. It is defined by a list of xy-coordinates of vertices from the start-point to the end-point in order,
and always turns 90 degrees at each vertex.
A single polygonal line does not pass the same point twice.

Two polygonal lines have the same shape when they
fully overlap each other only with rotation and translation
within xy-plane (i.e. without magnification or a flip).
The vertices given in reverse order from the start-point to the end-point is the
same as that given in order.

Figure 1 shows examples of polygonal lines.
In this figure, polygonal lines A and B have the same shape.

Write a program that answers polygonal lines which have the same shape as
the template.

Figure 1: Polygonal lines

Input

The input consists of multiple datasets.
The end of the input is indicated by a line which contains a zero.

A dataset is given as follows.

n

Polygonal line0

Polygonal line1

Polygonal line2

...

Polygonal linen

n is the number of polygonal lines for the object of search on
xy-plane.
n is an integer, and 1 <= n <= 50.
Polygonal line0 indicates the template.

A polygonal line is given as follows.

m

x1 y1

x2 y2

...

xm ym

m is the number of the vertices of a polygonal line (3 <= m <= 10).

xi and yi, separated by a space,
are the x- and y-coordinates
of a vertex, respectively (-10000 < xi < 10000, -10000 <yi < 10000).

Output

For each dataset in the input, your program should report numbers assigned to the polygonal lines that have the same shape as the template, in ascending order.
Each number must be written in a separate line without any other characters such as leading or trailing spaces.

Five continuous "+"s must be placed in a line at the end of each dataset.

Sample Input

5
5
0 0
2 0
2 1
4 1
4 0
5
0 0
0 2
-1 2
-1 4
0 4
5
0 0
0 1
-2 1
-2 2
0 2
5
0 0
0 -1
2 -1
2 0
4 0
5
0 0
2 0
2 -1
4 -1
4 0
5
0 0
2 0
2 1
4 1
4 0
4
4
-60 -75
-60 -78
-42 -78
-42 -6
4
10 3
10 7
-4 7
-4 40
4
-74 66
-74 63
-92 63
-92 135
4
-12 22
-12 25
-30 25
-30 -47
4
12 -22
12 -25
30 -25
30 47
3
5
-8 5
-8 2
0 2
0 4
8 4
5
-3 -1
0 -1
0 7
-2 7
-2 16
5
-1 6
-1 3
7 3
7 5
16 5
5
0 1
0 -2
8 -2
8 0
17 0
0

Output for the Sample Input

1
3
5
+++++
3
4
+++++
+++++


import java.util.*;

public class Main {
	int cnt, min;
	int[][] cost;

	void check(int[] perm){
		int sum = 0;
		for(int i=0;i<cnt-1;i++) sum += cost[perm[i]][perm[i+1]];
		min = Math.min(min, sum);
	}

	void makeperm(int k, int[] perm, boolean[] flag){
		if(k==cnt){
			check(perm);
		}else{
			for(int i=1;i<cnt;i++){
				if(flag[i]==true) continue;
				perm[k] = i;
				flag[i] = true;
				makeperm(k+1, perm, flag);
				flag[i] = false;
			}
		}
	}

	void solve(){
		Scanner sc = new Scanner(System.in);

		while(true){
			int w = sc.nextInt();
			int h = sc.nextInt();
			if(w==0 && h==0) break;

			char[][] map = new char[h][w];
			int[] x = new int[11];
			int[] y = new int[11];
			cnt = 1;
			for(int i=0;i<h;i++){
				String s = sc.next();
				for(int j=0;j<w;j++){
					char t = s.charAt(j);
					if(t=='o'){
						x[0] = j;
						y[0] = i;
					}else if(t=='*'){
						x[cnt] = j;
						y[cnt] = i;
						cnt++;
					}
					map[i][j] = t;
				}
			}

			cost = new int[cnt][cnt];
			int[] xx = new int[]{0,0,1,-1};
			int[] yy = new int[]{1,-1,0,0};
			boolean f = false;
			for(int i=0;i<cnt;i++){
				for(int j=i+1;j<cnt;j++){
					ArrayDeque<Integer> p = new ArrayDeque<Integer>();
					ArrayDeque<Integer> q = new ArrayDeque<Integer>();
					int[][] c = new int[h][w];
					for(int s=0;s<h;s++){
						for(int t=0;t<w;t++) c[s][t] = Integer.MAX_VALUE;
					}

					p.offer(x[i]);
					q.offer(y[i]);
					c[y[i]][x[i]] = 0;
					while(p.size()!=0){
						int u = p.poll();
						int v = q.poll();
						if(u==x[j] && v==y[j]) break;

						for(int s=0;s<4;s++){
							if(0<=u+xx[s] && u+xx[s]<w && 0<=v+yy[s] && v+yy[s]<h){
								if(map[v+yy[s]][u+xx[s]]!='x' && c[v][u]+1<c[v+yy[s]][u+xx[s]]){
									p.offer(u+xx[s]);
									q.offer(v+yy[s]);
									c[v+yy[s]][u+xx[s]] = c[v][u]+1;
								}
							}
						}
					}

					if(c[y[j]][x[j]]==Integer.MAX_VALUE){
						f = true;
						break;
					}
					cost[i][j] = cost[j][i] = c[y[j]][x[j]];
				}
				if(f==true) break;
			}

			if(f==false){
				min = Integer.MAX_VALUE;
				makeperm(1, new int[cnt], new boolean[cnt]);
				System.out.println(min);
			}else{
				System.out.println(-1);
			}
		}
	}

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

Problem F: Cleaning Robot

Here, we want to solve path planning for a mobile robot cleaning a
rectangular room floor with furniture.

Consider the room floor paved with square tiles whose size fits
the cleaning robot (1 × 1).
There are 'clean tiles' and 'dirty tiles', and the robot can change
a 'dirty tile' to a 'clean tile' by visiting the tile.
Also there may be some obstacles (furniture) whose size fits a
tile in the room. If there is an obstacle on a tile, the robot cannot visit
it.
The robot moves to an adjacent tile with one move.
The tile onto which the robot moves must be one of four tiles
(i.e., east, west, north or south) adjacent to the tile where the
robot is present. The robot may visit a tile twice or more.

Your task is to write a program which computes the minimum number of
moves for the robot to change all 'dirty tiles' to 'clean tiles',
if ever possible.

Input

The input consists of multiple maps, each representing the size
and arrangement of the room. A map is given in the following format.

w h

c11 c12 c13 ... c1w

c21 c22 c23 ... c2w

...

ch1 ch2 ch3 ... chw

The integers w and h are the lengths of the two sides
of the floor of the room in terms of widths of floor tiles. w and h
are less than or equal to 20. The character cyx represents
what is initially on the tile with coordinates (x, y) as follows.

'.' : a clean tile

'*' : a dirty tile

'x' : a piece of furniture (obstacle)

'o' : the robot (initial position)

In the map the number of 'dirty tiles' does not exceed 10.
There is only one 'robot'.

The end of the input is indicated by a line containing two zeros.

Output

For each map, your program should output a line containing the minimum
number of moves. If the map includes 'dirty tiles' which the robot cannot reach,
your program should output -1.

Sample Input

7 5
.......
.o...*.
.......
.*...*.
.......
15 13
.......x.......
...o...x....*..
.......x.......
.......x.......
.......x.......
...............
xxxxx.....xxxxx
...............
.......x.......
.......x.......
.......x.......
..*....x....*..
.......x.......
10 10
..........
..o.......
..........
..........
..........
.....xxxxx
.....x....
.....x.*..
.....x....
.....x....
0 0

Output for the Sample Input

8
49
-1


import java.util.Scanner;

public class Main {

	/**
	 * @param args
	 */

	//最大値は1000000
	public static final int MAX_NUMBER = 1000000;

	public static void main(String[] args) {
		dirichlet();
		//fortune();

	}

	public static void dirichlet(){

		Scanner sc = new Scanner(System.in);

		boolean isNotPrime[] = new boolean[MAX_NUMBER];
		//System.out.println("aaa");
		//エラトステネスの古いにかける
		isNotPrime[0] = true;
		isNotPrime[1] = true;
		isNotPrime[2] = false;
		int n1 = 0;
		for(int i = 2; i < MAX_NUMBER; i++){
			if(isNotPrime[i] == false){
				for(int j = 2; j < MAX_NUMBER / i; j++){
					isNotPrime[i * j] = true;
				}
			}

			if(MAX_NUMBER < i * i){
				break;
			}

		}

		/*isNotPrime[0] = false;
		isNotPrime[1] = false;
		isNotPrime[2] = true;
		int n1 = 0;
		for(int i = 3; i < MAX_NUMBER; i += 2){
			isNotPrime[i] = true;
			for(int j = 2; j <= i/2; j++){
				if(i % j == 0){
					isNotPrime[i] = false;
					n1++;
					System.out.println(n1 + " " + i);
					break;
				}
			}
		}*/
		//System.out.println("END!!");
		//Scanner sc = new Scanner(System.in);

		int a = sc.nextInt();
		int d = sc.nextInt();
		int n = sc.nextInt();
		while(a != 0 || d != 0 || n != 0){
			int sum = 0;
			int num = 0;
			sum = a;
			while(num < n){
				if(isNotPrime[sum] == false){
					num++;
				}
				sum += d;
			}
			System.out.println(sum - d);
			a = sc.nextInt();
			d = sc.nextInt();
			n = sc.nextInt();
		}

	}

}

Problem A: Dirichlet's Theorem on Arithmetic Progressions

Good evening, contestants.

If a and d are relatively prime positive integers,
the arithmetic sequence beginning with a
and increasing by d, i.e.,
a,
a + d,
a + 2d,
a + 3d,
a + 4d,
...,
contains infinitely many prime numbers.
This fact is known as Dirichlet's Theorem on Arithmetic Progressions,
which had been conjectured by Johann Carl Friedrich Gauss (1777 - 1855)
and was proved by Johann Peter Gustav Lejeune Dirichlet (1805 - 1859)
in 1837.

For example,
the arithmetic sequence beginning with 2 and increasing by 3,
i.e.,

2,
5,
8,
11,
14,
17,
20,
23,
26,
29,
32,
35,
38,
41,
44,
47,
50,
53,
56,
59,
62,
65,
68,
71,
74,
77,
80,
83,
86,
89,
92,
95,
98,
...
,

contains infinitely many prime numbers

2,
5,
11,
17,
23,
29,
41,
47,
53,
59,
71,
83,
89,
...

.

Your mission, should you decide to accept it,
is to write a program to find
the nth prime number in this arithmetic sequence
for given positive integers a, d, and n.

As always, should you or any of your team be tired or confused,
the secretary disavow any knowledge of your actions.
This judge system will self-terminate in three hours.
Good luck!

Input

The input is a sequence of datasets.
A dataset is a line containing three positive integers
a, d, and n separated by a space.
a and d are relatively prime.
You may assume a <= 9307, d <= 346,
and n <= 210.

The end of the input is indicated by a line
containing three zeros separated by a space.
It is not a dataset.

Output

The output should be composed of
as many lines as the number of the input datasets.
Each line should contain a single integer
and should never contain extra characters.

The output integer corresponding to
a dataset a, d, n should be
the nth
prime number among those contained
in the arithmetic sequence beginning with a
and increasing by d.

FYI, it is known that the result is always less than
106 (one million)
under this input condition.

Sample Input

367 186 151
179 10 203
271 37 39
103 230 1
27 104 185
253 50 85
1 1 1
9075 337 210
307 24 79
331 221 177
259 170 40
269 58 102
0 0 0

Output for the Sample Input

92809
6709
12037
103
93523
14503
2
899429
5107
412717
22699
25673


import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while (true) {
			int n = sc.nextInt();
			if (n == 0)
				break;
			int max = 0, min = 1000, sum = 0;
			for (int i = 0; i < n; i++) {
				int score = sc.nextInt();
				sum += score;
				if (max < score)
					max = score;
				if (min > score)
					min = score;
			}
			System.out.println((sum - max - min) / (n - 2));
		}
	}
}

Problem A: ICPC Score Totalizer Software

The International Clown and Pierrot Competition (ICPC), is one of the
most distinguished and also the most popular events on earth in the
show business.

One of the unique features of this contest is the great number of
judges that sometimes counts up to one hundred. The number of judges
may differ from one contestant to another, because judges with any
relationship whatsoever with a specific contestant are temporarily
excluded for scoring his/her performance.

Basically, scores given to a contestant's performance by the judges
are averaged to decide his/her score. To avoid letting judges with
eccentric viewpoints too much influence the score, the highest and the
lowest scores are set aside in this calculation. If the same highest
score is marked by two or more judges, only one of them is ignored.
The same is with the lowest score. The average, which may contain
fractions, are truncated down to obtain final score as an integer.

You are asked to write a program that computes the scores of
performances, given the scores of all the judges, to speed up the event
to be suited for a TV program.

Input

The input consists of a number of datasets, each corresponding to a
contestant's performance. There are no more than 20 datasets in the input.

A dataset begins with a line with an integer n, the number of
judges participated in scoring the performance (3 ≤ n ≤
100). Each of the n lines following it has an integral
score s (0 ≤ s ≤ 1000) marked by a judge. No
other characters except for digits to express these numbers are in the
input. Judges' names are kept secret.

The end of the input is indicated by a line with a single zero in it.

Output

For each dataset, a line containing a single decimal integer
indicating the score for the corresponding performance should be
output. No other characters should be on the output line.

Sample Input

3
1000
342
0
5
2
2
9
11
932
5
300
1000
0
200
400
8
353
242
402
274
283
132
402
523
0

Output for the Sample Input

342
7
300
326


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import static java.lang.Integer.parseInt;

/**
 * Cards
 */
public class Main {

	static final int INF = 1 << 29;

	static int S, T;
	static List<List<Edge>> G;
	static boolean[] used;

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String line;
		String[] words;

		while ((line = br.readLine()) != null && !line.isEmpty()) {

			int m, n;
			m = parseInt(line.substring(0, line.indexOf(' ')));
			n = parseInt(line.substring(line.indexOf(' ') + 1));
			if ((m | n) == 0) break;

			S = m + n;
			T = S + 1;

			int[] ms = new int[m];
			int[] ns = new int[n];

			for (int i = 0; i < m; ) {
				StringTokenizer st = new StringTokenizer(br.readLine());
				while (st.hasMoreTokens()) {
					ms[i] = parseInt(st.nextToken());
					i++;
				}
			}

			for (int i = 0; i < n; ) {
				StringTokenizer st = new StringTokenizer(br.readLine());
				while (st.hasMoreTokens()) {
					ns[i] = parseInt(st.nextToken());
					i++;
				}
			}

			//
			G = new ArrayList<>();
			used = new boolean[T + 1];

			for (int i = 0; i <= T; i++) {
				G.add(new ArrayList<>());
			}

			//S -> blue
			for (int i = 0; i < m; i++) {
				G.get(S).add(new Edge(i, 1, G.get(i).size()));
				G.get(i).add(new Edge(S, 0, G.get(S).size() - 1));
			}

			//red -> T
			for (int i = m; i < m + n; i++) {
				G.get(i).add(new Edge(T, 1, G.get(T).size()));
				G.get(T).add(new Edge(i, 0, G.get(i).size() - 1));
			}

			//blue -> red
			for (int i = 0; i < m; i++) {
				for (int j = 0; j < n; j++) {
					if (gcd(ms[i], ns[j]) > 1) {
						G.get(i).add(new Edge(m + j, 1, G.get(m + j).size()));
						G.get(m + j).add(new Edge(i, 0, G.get(i).size() - 1));
					}
				}
			}

			int ans = 0;

			while (true) {
				used = new boolean[T + 1];
				int f = rec(S, T, INF);
				if (f == 0) break;
				ans += f;
			}

			System.out.println(ans);
		}
	}

	static int rec(int u, int v, int f) {

		if (u == v) return f;

		used[u] = true;

		for (Edge e : G.get(u)) {
			if (!used[e.to] && e.cap > 0) {
				int d = rec(e.to, v, Math.min(f, e.cap));
				if (d > 0) {
					e.cap -= d;
					G.get(e.to).get(e.rev).cap += d;
					return d;
				}
			}
		}

		return 0;
	}

	static int gcd(int a, int b) {
		if (b == 0) return a;
		return gcd(b, a % b);
	}
}

class Edge {
	int to, cap, rev;

	public Edge(int to, int cap, int rev) {
		this.to = to;
		this.cap = cap;
		this.rev = rev;
	}
}

Problem E: Cards

There are many blue cards and red cards on the table.
For each card, an integer number greater than 1 is printed on its face.
The same number may be printed on several cards.

A blue card and a red card can be paired when both of the numbers
printed on them have a common divisor greater than 1.
There may be more than one red card that can be paired with one blue card.
Also, there may be more than one blue card that can be paired with one red card.
When a blue card and a red card are chosen and paired,
these two cards are removed from the whole cards on the table.

Figure E-1: Four blue cards and three red cards

For example, in Figure E-1,
there are four blue cards and three red cards.
Numbers 2, 6, 6 and 15 are printed on the faces of the four blue cards,
and 2, 3 and 35 are printed on those of the three red cards.
Here, you can make pairs of blue cards and red cards as follows.
First,
the blue card with number 2 on it and the red card with 2 are paired and removed.
Second,
one of the two blue cards with 6 and the red card with 3 are paired and removed.
Finally,
the blue card with 15 and the red card with 35 are paired and removed.
Thus the number of removed pairs is three.

Note that the total number of the pairs depends on
the way of choosing cards to be paired.
The blue card with 15 and the red card with 3 might be paired
and removed at the beginning.
In this case, there are only one more pair that can be removed
and the total number of the removed pairs is two.

Your job is to find the largest number of pairs that can be removed from the given set of cards on the table.

Input

The input is a sequence of datasets.
The number of the datasets is less than or equal to 100.
Each dataset is formatted as follows.

m n

b1 ... bk
... bm

r1 ... rk
... rn

The integers m and n are the number of blue cards
and that of red cards, respectively.
You may assume 1 ≤ m ≤ 500 and 1≤ n ≤ 500.

bk (1 ≤ k ≤ m) and
rk (1 ≤ k ≤ n) are
numbers printed on the blue cards and the red cards respectively,
that are integers greater than or equal to 2 and less than
10000000 (=107).
The input integers are separated by a space or a newline.
Each of bm and rn is
followed by a newline.
There are no other characters in the dataset.

The end of the input is indicated by a line containing two zeros
separated by a space.

Output

For each dataset, output a line containing an integer that indicates
the maximum of the number of the pairs.

Sample Input

4 3
2 6 6 15
2 3 5
2 3
4 9
8 16 32
4 2
4 9 11 13
5 7
5 5
2 3 5 1001 1001
7 11 13 30 30
10 10
2 3 5 7 9 11 13 15 17 29
4 6 10 14 18 22 26 30 34 38
20 20
195 144 903 63 137 513 44 626 75 473
876 421 568 519 755 840 374 368 570 872
363 650 155 265 64 26 426 391 15 421
373 984 564 54 823 477 565 866 879 638
100 100
195 144 903 63 137 513 44 626 75 473
876 421 568 519 755 840 374 368 570 872
363 650 155 265 64 26 426 391 15 421
373 984 564 54 823 477 565 866 879 638
117 755 835 683 52 369 302 424 513 870
75 874 299 228 140 361 30 342 750 819
761 123 804 325 952 405 578 517 49 457
932 941 988 767 624 41 912 702 241 426
351 92 300 648 318 216 785 347 556 535
166 318 434 746 419 386 928 996 680 975
231 390 916 220 933 319 37 846 797 54
272 924 145 348 350 239 563 135 362 119
446 305 213 879 51 631 43 755 405 499
509 412 887 203 408 821 298 443 445 96
274 715 796 417 839 147 654 402 280 17
298 725 98 287 382 923 694 201 679 99
699 188 288 364 389 694 185 464 138 406
558 188 897 354 603 737 277 35 139 556
826 213 59 922 499 217 846 193 416 525
69 115 489 355 256 654 49 439 118 961
0 0

Output for the Sample Input

3
1
0
4
9
18
85


import java.util.Arrays;
import java.util.Scanner;

public class Main {

	static final int OP = 105;
	static int[][][] field;
	static int[][] right_ref ={{},
		{0,0,3,5,2,4,0},
		{0,4,0,1,6,0,3},
		{0,2,6,0,0,1,5},
		{0,5,1,0,0,6,2},
		{0,3,0,6,1,0,4},
		{0,0,4,2,5,3,0}};

	static int Setting(int x, int y){
		for(int i=0;;i++){
			if(field[i][x][y]==0){
				return i;
			}
		}
	}

	static void Taosu(int floor, int top, int front, int right){
		int x=OP, y=OP;
		while(true){
			int un_floor = floor-1;
			int flag = 0;
			int max = 0;
			if(un_floor==-1){
				return;
			}
			if(field[un_floor][x-1][y]==0&&front>=4){
				flag = 1;
				max=front;
			}
			if(field[un_floor][x+1][y]==0&&front<=3){
				if(max<7-front){
					flag = 2;
					max=7-front;
				}
			}
			if(field[un_floor][x][y-1]==0&&right<=3){
				if(max<7-right){
					flag = 3;
					max = 7-right;
				}
			}
			if(field[un_floor][x][y+1]==0&&right>=4){
				if(max<right){
					flag = 4;
				}
			}
			if(flag==0){
				return;
			}
			else{
				int put = 0;
				if(flag==1){
					put = Setting(x-1,y);
					field[put][x-1][y] = 7-front;
					field[floor][x][y] = 0;
					int tmp = front;
					front = top;
					top = 7-tmp;
					x--;
				}
				else if(flag==2){
					put = Setting(x+1,y);
					field[put][x+1][y] = front;
					field[floor][x][y] = 0;
					int tmp = front;
					front = 7-top;
					top = tmp;
					x++;
				}
				else if(flag==3){
					put = Setting(x,y-1);
					field[put][x][y-1] = right;
					field[floor][x][y] = 0;
					int tmp = top;
					top = right;
					right = 7-tmp;
					y--;
				}
				else if(flag==4){
					put = Setting(x,y+1);
					field[put][x][y+1] = 7-right;
					field[floor][x][y] = 0;
					int tmp = top;
					top = 7-right;
					right = tmp;
					y++;
				}
				floor = put;
			}
		}
	}
	public static void main(String[] args) {
		Scanner stdIn = new Scanner(System.in);

		while(true){
			int n = stdIn.nextInt();
			if(n==0){
				return;
			}
			int[] fall_top = new int[n];
			int[] fall_front = new int[n];
			field = new int[110][210][210];
			for(int i=0;i<n;i++){
				fall_top[i] = stdIn.nextInt();
				fall_front[i] = stdIn.nextInt();
			}

			for(int i=0;i<n;i++){
				int tmp = Setting(OP,OP);
				field[tmp][OP][OP] = fall_top[i];
				Taosu(tmp,fall_top[i],fall_front[i],right_ref[fall_top[i]][fall_front[i]]);
			}

			int[] output = new int[7];
			Arrays.fill(output, 0);
			for(int j=0;j<210;j++){
				for(int k=0;k<210;k++){
					for(int i=0;i<109;i++){
						if(field[i+1][j][k]==0&&field[i][j][k]!=0){
							output[field[i][j][k]]++;
						}
						else if(field[i][j][k]==0){
							break;
						}
					}
				}
			}
			for(int i=1;i<6;i++){
				System.out.print(output[i]+" ");
			}
			System.out.println(output[6]);
		}
	}
}

Biased Dice

Professor Random, known for his research on randomized algorithms, is now conducting an experiment on biased dice. His experiment consists of dropping a number of dice onto a plane, one after another from a fixed position above the plane. The dice fall onto the plane or dice already there, without rotating, and may roll and fall according to their property. Then he observes and records the status of the stack formed on the plane, specifically, how many times each number appears on the faces visible from above. All the dice have the same size and their face numbering is identical, which we show in Figure C-1.

Figure C-1: Numbering of a die

The dice have very special properties, as in the following.

(1) Ordinary dice can roll in four directions, but the dice used in this experiment never roll in the directions of faces 1, 2 and 3; they can only roll in the directions of faces 4, 5 and 6. In the situation shown in Figure C-2, our die can only roll to one of two directions.

Figure C-2: An ordinary die and a biased die

(2) The die can only roll when it will fall down after rolling, as shown in Figure C-3. When multiple possibilities exist, the die rolls towards the face with the largest number among those directions it can roll to.

Figure C-3: A die can roll only when it can fall

(3) When a die rolls, it rolls exactly 90 degrees, and then falls straight down until its bottom face touches another die or the plane, as in the case [B] or [C] of Figure C-4.

(4) After rolling and falling, the die repeatedly does so according to the rules (1) to (3) above.

Figure C-4: Example stacking of biased dice

For example, when we drop four dice all in the same orientation, 6 at the top and 4 at the front, then a stack will be formed as shown in Figure C-4.

Figure C-5: Example records

After forming the stack, we count the numbers of faces with 1 through 6 visible from above and record them. For example, in the left case of Figure C-5, the record will be "0 2 1 0 0 0", and in the right case, "0 1 1 0 0 1".

Input

The input consists of several datasets each in the following format.

n

t1  f1

t2  f2

...

tn  fn

Here, n (1 ≤ n ≤ 100) is an integer and is the number of the dice to be dropped. ti and fi (1 ≤ ti, fi ≤ 6) are two integers separated by a space and represent the numbers on the top and the front faces of the i-th die, when it is released, respectively.

The end of the input is indicated by a line containing a single zero.

Output

For each dataset, output six integers separated by a space. The integers represent the numbers of faces with 1 through 6 correspondingly, visible from above. There may not be any other characters in the output.

Sample Input

4
6 4
6 4
6 4
6 4
2
5 3
5 3
8
4 2
4 2
4 2
4 2
4 2
4 2
4 2
4 2
6
4 6
1 5
2 3
5 3
2 4
4 2
0

Output for the Sample Input

0 1 1 0 0 1
1 0 0 0 1 0
1 2 2 1 0 0
2 3 0 0 0 0


import java.util.Scanner;

public class Main {
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		int[] h = new int[100000];
		int[] w = new int[100000];
		int[] t = new int[100000];
		int n = 0;
		int a =1;
		int k=0;
		suuzi[] p =new suuzi[150*150];
		int q =0;
		int g=0;
		suuzi r ;
		suuzi b = new suuzi();
		for(int i=0;i<100000;i++){
			h[i]=sc.nextInt();
			w[i]=sc.nextInt();
			t[i]=h[i]*h[i]+w[i]*w[i];
			if(h[i]==0&&w[i]==0){
				n=i;
				break;
			}

		}
		for(int l=1;l<=150;l++){
			for(k=l+1;k<=150;k++){
				suuzi m = new suuzi();
				m.x=l;
				m.y=k;
				m.z=l*l+k*k;
				p[q]=m;
				q=q+1;
			}
		}
		q=q-1;
	   while(a==1){
		   a=0;
		   for(int i=0;i<q;i++){
			   if(p[i].z>p[i+1].z){
				   r=p[i];
				   p[i]=p[i+1];
				   p[i+1]=r;
				   a=1;
			   }
			   if(p[q].z==p[i+1].z&&p[i].x>p[i+1].x){
				   r=p[i];
				   p[i]=p[i+1];
				   p[i+1]=r;
				   a=1;
			   }

		   }
	   }

		while(g<n-1){
			b.x =h[g];
			b.y =w[g];
			g=g+1;
				for(int l=0;l<q;l++){
					if(b.x==p[l].x&&b.y==p[l].y){
						System.out.println(p[l+1].x+" "+p[l+1].y);

		}

	}
				while(g==n-1){
					b.x =h[g];
					b.y =w[g];
					g=g+1;
						for(int l=0;l<q;l++){
							if(b.x==p[l].x&&b.y==p[l].y){
								System.out.println(p[l+1].x+" "+p[l+1].y);

				}

			}
				}

}
	}
}
class suuzi{
	int x;int y;int z;
}

Integral Rectangles

Let us consider rectangles whose height, h, and
width, w, are both integers. We call such rectangles
integral rectangles. In this problem, we consider only wide
integral rectangles, i.e., those with w > h.

We define the following ordering of wide integral rectangles. Given
two wide integral rectangles,

The one shorter in its diagonal line is smaller, and

If the two have diagonal lines with the same length, the one shorter
in its height is smaller.

Given a wide integral rectangle, find the smallest wide integral
rectangle bigger than the given one.

Input

The entire input consists of multiple datasets. The number of
datasets is no more than 100. Each dataset describes a wide integral
rectangle by specifying its height and width, namely h
and w, separated by a space in a line, as follows.

h w

For each dataset, h and w (>h) are both
integers greater than 0 and no more than 100.

The end of the input is indicated by a line of two zeros separated by a space.

Output

For each dataset, print in a line two numbers describing the
height and width, namely h and w (> h), of the
smallest wide integral rectangle bigger than the one described in the
dataset. Put a space between the numbers. No other
characters are allowed in the output.

For any wide integral rectangle given in the input, the width and
height of the smallest wide integral rectangle bigger than the given
one are both known to be not greater than 150.

In addition, although
the ordering of wide integral rectangles uses the comparison of
lengths of diagonal lines, this comparison can be replaced with that
of squares (self-products) of lengths of diagonal lines, which can
avoid unnecessary troubles possibly caused by the use of floating-point
numbers.

Sample Input

1 2
1 3
2 3
1 4
2 4
5 6
1 8
4 7
98 100
99 100
0 0

Output for the Sample Input

1 3
2 3
1 4
2 4
3 4
1 8
4 7
2 8
3 140
89 109


import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.NoSuchElementException;

public class Main {

	static PrintWriter out;
	static InputReader ir;
	static boolean debug = false;

	static void solve() {
		for (;;) {
			int n = ir.nextInt();
			if (n == 0)
				return;
			int[] p = ir.nextIntArray(n - 1);
			int[] d = ir.nextIntArray(n - 1);
			Graph[] g = new Graph[n];
			long[][] adj = new long[n][n];
			for (int i = 0; i < n; i++) {
				Arrays.fill(adj[i], Long.MAX_VALUE / 2);
				adj[i][i] = 0;
			}
			long ret = 0;
			boolean[] l = new boolean[n];
			for (int i = 0; i < n; i++)
				g[i] = new Graph();
			for (int i = 1; i < n; i++) {
				g[i].add(new int[] { p[i - 1] - 1, d[i - 1] });
				g[p[i - 1] - 1].add(new int[] { i, d[i - 1] });
				ret += d[i - 1];
			}
			for (int i = 0; i < n; i++)
				if (g[i].size() == 1)
					l[i] = true;
			for (int i = 0; i < n; i++) {
				if (l[i])
					continue;
				for (int j = 0; j < g[i].size(); j++) {
					int[] to = g[i].get(j);
					if (l[to[0]])
						continue;
					adj[i][to[0]] = to[1];
					ret += to[1];
				}
			}
			for (int k = 0; k < n; k++) {
				if (l[k])
					continue;
				for (int i = 0; i < n; i++) {
					if (l[i])
						continue;
					for (int j = 0; j < n; j++) {
						if (l[j])
							continue;
						adj[i][j] = Math.min(adj[i][j], adj[i][k] + adj[k][j]);
					}
				}
			}
			long ma = 0;
			for (int i = 0; i < n; i++)
				for (int j = 0; j < i; j++)
					if (adj[i][j] != Long.MAX_VALUE / 2)
						ma = Math.max(ma, adj[i][j]);
			out.println(ret - ma);
		}
	}

	static class Graph extends ArrayList<int[]> {
	}

	public static void main(String[] args) throws Exception {
		ir = new InputReader(System.in);
		out = new PrintWriter(System.out);
		solve();
		out.flush();
	}

	static class InputReader {

		private InputStream in;
		private byte[] buffer = new byte[1024];
		private int curbuf;
		private int lenbuf;

		public InputReader(InputStream in) {
			this.in = in;
			this.curbuf = this.lenbuf = 0;
		}

		public boolean hasNextByte() {
			if (curbuf >= lenbuf) {
				curbuf = 0;
				try {
					lenbuf = in.read(buffer);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (lenbuf <= 0)
					return false;
			}
			return true;
		}

		private int readByte() {
			if (hasNextByte())
				return buffer[curbuf++];
			else
				return -1;
		}

		private boolean isSpaceChar(int c) {
			return !(c >= 33 && c <= 126);
		}

		private void skip() {
			while (hasNextByte() && isSpaceChar(buffer[curbuf]))
				curbuf++;
		}

		public boolean hasNext() {
			skip();
			return hasNextByte();
		}

		public String next() {
			if (!hasNext())
				throw new NoSuchElementException();
			StringBuilder sb = new StringBuilder();
			int b = readByte();
			while (!isSpaceChar(b)) {
				sb.appendCodePoint(b);
				b = readByte();
			}
			return sb.toString();
		}

		public int nextInt() {
			if (!hasNext())
				throw new NoSuchElementException();
			int c = readByte();
			while (isSpaceChar(c))
				c = readByte();
			boolean minus = false;
			if (c == '-') {
				minus = true;
				c = readByte();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res = res * 10 + c - '0';
				c = readByte();
			} while (!isSpaceChar(c));
			return (minus) ? -res : res;
		}

		public long nextLong() {
			if (!hasNext())
				throw new NoSuchElementException();
			int c = readByte();
			while (isSpaceChar(c))
				c = readByte();
			boolean minus = false;
			if (c == '-') {
				minus = true;
				c = readByte();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res = res * 10 + c - '0';
				c = readByte();
			} while (!isSpaceChar(c));
			return (minus) ? -res : res;
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public int[] nextIntArray(int n) {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		public long[] nextLongArray(int n) {
			long[] a = new long[n];
			for (int i = 0; i < n; i++)
				a[i] = nextLong();
			return a;
		}

		public char[][] nextCharMap(int n, int m) {
			char[][] map = new char[n][m];
			for (int i = 0; i < n; i++)
				map[i] = next().toCharArray();
			return map;
		}
	}

	static void tr(Object... o) {
		if (debug)
			out.println(Arrays.deepToString(o));
	}
}

Bridge Removal

ICPC islands once had been a popular tourist destination.
For nature preservation, however, the government decided to prohibit entrance to the islands,
and to remove all the man-made structures there.
The hardest part of the project is to remove all the bridges connecting the islands.

There are n islands and n-1 bridges.
The bridges are built so that all the islands are reachable from all the other islands by
crossing one or more bridges.
The bridge removal team can choose any island as the starting point, and can repeat either of the
following steps.

Move to another island by crossing a bridge that is connected to the current island.

Remove one bridge that is connected to the current island, and stay at the same island after the removal.

Of course, a bridge, once removed, cannot be crossed in either direction.
Crossing or removing a bridge both takes time proportional to the length of the bridge.
Your task is to compute the shortest time necessary for removing all the bridges.
Note that the island where the team starts can differ from where the team finishes the work.

Input

The input consists of at most 100 datasets.
Each dataset is formatted as follows.

n

p2 p3 ... pn

d2 d3 ... dn

The first integer n (3 ≤ n ≤ 800) is the number of the islands.
The islands are numbered from 1 to n.
The second line contains n-1 island numbers pi
(1 ≤ pi < i), and tells that for each i
from 2 to n the island i and the island pi are connected by a bridge.
The third line contains n-1 integers di (1 ≤ di ≤ 100,000)
each denoting the length of the corresponding bridge.
That is, the length of the bridge connecting the island i and pi
is di. It takes di units of time to cross the bridge, and
also the same units of time to remove it.

Note that, with this input format, it is assured that all the islands are reachable each other by
crossing one or more bridges.

The input ends with a line with a single zero.

Output

For each dataset, print the minimum time units required to remove all the bridges in a single line.
Each line should not have any character other than this number.

Sample Input

4
1 2 3
10 20 30
10
1 2 2 1 5 5 1 8 8
10 1 1 20 1 1 30 1 1
3
1 1
1 1
0

Output for the Sample Input

80
136
2


import java.util.Scanner;

public class Main {
	private static final int N_MAX = 2 << 15;
	private boolean[] era;
	private void run() {
		era = new boolean [ N_MAX + 1 ];
		era[ 1 ] = true;
		for( int i = 2; i <= N_MAX; i++ ) {
			if( era[ i ] ) { continue; }
			for( int j = i * 2; j <= N_MAX; j = j + i ) {
				era[ j ] = true;
			}
		}

		Scanner sc = new Scanner( System.in );
		while( sc.hasNext() ) {
			int counter = 0;
			int n = sc.nextInt();
			if( n == 0 ) { break; }
			for( int p1 = 2; p1 <= n / 2; p1++ ) {
				if( era[ p1 ] ) { continue; }
				if( !era[ n - p1 ] ) {
					counter++;
				}
			}
			System.out.println( counter );
		}

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

Problem A:Goldbach's Conjecture

Goldbach's Conjecture: For any even number n greater than or equal to 4, there exists at least one pair of prime numbers p1 and p2 such that n = p1 + p2.

This conjecture has not been proved nor refused yet. No one is sure whether this conjecture actually holds. However, one can find such a pair of prime numbers, if any, for a given even number. The problem here is to write a program that reports the number of all the pairs of prime numbers satisfying the condition in the conjecture for a given even number.

A sequence of even numbers is given as input. Corresponding to each number, the program should output the number of pairs mentioned above. Notice that we are intereseted in the number of essentially different pairs and therefore you should not count (p1, p2) and (p2, p1) separately as two different pairs.

Input

An integer is given in each input line. You may assume that each integer is even, and is greater than or equal to 4 and less than 215. The end of the input is indicated by a number 0.

Output

Each output line should contain an integer number. No other characters should appear in the output.

Sample Input

6
10
12
0

Output for the Sample Input

1
2
1


public class Main {
	public static void main(String[] args) {
		java.util.Scanner sc = new java.util.Scanner(System.in);
		while (true) {
			int n = sc.nextInt();
			int m = sc.nextInt();
			int k = sc.nextInt();
			if (n == 0 && m == 0 && k == 0)
				break;
			int[] dice = new int[n];
			int[] result = new int[n * m + 1];
			java.util.Arrays.fill(dice, 1);
			out: while (true) {
				int pointer = n - 1;
				result[Math.max(1, sum(dice) - k)]++;
				if (dice[pointer] < m) {
					dice[pointer]++;
					continue;
				}
				while (dice[pointer] == m) {
					pointer--;
					if (pointer < 0)
						break out;
				}
				dice[pointer]++;
				while (pointer != n - 1) {
					pointer++;
					dice[pointer] = 1;
				}
			}
			double p = 0;
			for (int i = 0; i < result.length; i++) {
				p += (double) i * result[i] / Math.pow(m, n);
			}
			System.out.println(p);
		}
		sc.close();
	}

	static int sum(int[] dice) {
		int sum = 0;
		for (int i = 0; i < dice.length; i++)
			sum += dice[i];
		return sum;
	}
}

Problem B: Expected Allowance

Hideyuki is allowed by his father Ujisato some 1000 yen bills every month for his pocket money.
In the first day of every month, the number of bills is decided as follows. Ujisato prepares n
pieces of m-sided dice and declares the cutback k. Hideyuki rolls these dice. The number of
bills given is the sum of the spots of the rolled dice decreased by the cutback. Fortunately to
Hideyuki, Ujisato promises him to give at least one bill, even if the sum of the spots does not
exceed the cutback. Each of the dice has spots of 1 through m inclusive on each side, and the
probability of each side is the same.

In this problem, you are asked to write a program that finds the expected value of the number
of given bills.

For example, when n = 2, m = 6 and k = 3, the probabilities of the number of bills being 1, 2, 3, 4, 5, 6, 7, 8 and 9 are 1/36 + 2/36 + 3/36, 4/36, 5/36, 6/36, 5/36, 4/36, 3/36, 2/36 and 1/36, respectively.

Therefore, the expected value is

(1/36 + 2/36 + 3/36) × 1 + 4/36 × 2 + 5/36 × 3 + 6/36 × 4 + 5/36 × 5 + 4/36 × 6 + 3/36 × 7 + 2/36 × 8 + 1/36 × 9, which is approximately 4.11111111.

Input

The input is a sequence of lines each of which contains three integers n, m and k in this order.
They satisfy the following conditions.

1 ≤ n

2 ≤ m

0 ≤ k < nm

nm × mn < 100000000 (108)

The end of the input is indicated by a line containing three zeros.

Output

The output should be comprised of lines each of which contains a single decimal fraction. It is
the expected number of bills and may have an error less than 10-7 . No other characters should
occur in the output.

Sample Input

2 6 0
2 6 3
3 10 9
13 3 27
1 2008 3
0 0 0

Output for the Sample Input

7.00000000
4.11111111
7.71000000
1.42902599
1001.50298805


import java.awt.*;
import java.util.*;
import java.awt.geom.*;

public class Main {
    public static void main(String args[])throws Exception{
        Scanner cin= new Scanner(System.in);
		int n,m;
		Point2D.Double[] w = new Point2D.Double[200];
		Point2D.Double[] b = new Point2D.Double[200];
		for(;;){
			n=cin.nextInt();
			m=cin.nextInt();
			//			System.out.printf("%d %d\n",n,m);

			if(n==0 && m==0) break;

			for(int i=0;i<n;i++){
				w[i] = new Point2D.Double();
				w[i].x= cin.nextInt();
				w[i].y= cin.nextInt();
			}
			for(int i=0;i<m;i++){
				b[i] = new Point2D.Double();
				b[i].x= cin.nextInt();
				b[i].y= cin.nextInt();
			}

			int f=0;
		out:
			for(int i=0;i<n;i++){
				for(int j=0;j<m;j++){
					int t1=0,t2=0;
					//					System.out.printf("%d  %d\n",i,j);
					for(int k=0;k<n;k++){
						if(k==i) continue;
						int ccw=Line2D.relativeCCW( w[k].x, w[k].y, w[i].x, w[i].y, b[j].x, b[j].y);
						//						if(ccw==0) if(w[i].distance(b[j]) + w[i].distance(w[k]) <= w[k].distance(b[j])) ccw=1;
						//						System.out.println(ccw);
						t1+=ccw;
					}
					for(int k=0;k<m;k++){
						if(k==j) continue;
						int ccw=Line2D.relativeCCW(b[k].x, b[k].y, b[j].x, b[j].y, w[i].x, w[i].y);
						//						System.out.println(ccw);
						//						if(ccw==0) if(b[j].distance(w[i]) + b[j].distance(b[k]) <= w[i].distance(b[k])) ccw=-1;
						//						System.out.println(ccw);
						t2+=ccw;
					}
					//					System.out.printf("t1,t2= %d,%d\n",t1,t2);
					if(t1>=0 && t2>=0 && Math.abs(t1)==n-1 && Math.abs(t2)==m-1){
						f=1;
						System.out.println("YES");
						break out;
					}
				}
			}
			if(f==0) System.out.println("NO");
		}
	}
}

Problem D: Separate Points

Numbers of black and white points are placed on a plane. Let's imagine that a straight line
of infinite length is drawn on the plane. When the line does not meet any of the points, the
line divides these points into two groups. If the division by such a line results in one group
consisting only of black points and the other consisting only of white points, we say that the
line "separates black and white points".

Let's see examples in Figure 3. In the leftmost example, you can easily find that the black and
white points can be perfectly separated by the dashed line according to their colors. In the
remaining three examples, there exists no such straight line that gives such a separation.

Figure 3: Example planes

In this problem, given a set of points with their colors and positions, you are requested to decide
whether there exists a straight line that separates black and white points.

Input

The input is a sequence of datasets, each of which is formatted as follows.

n m

x1 y1

.

.

.

xn yn

xn+1 yn+1

.

.

.

xn+m yn+m

The first line contains two positive integers separated by a single space; n is the number of black
points, and m is the number of white points. They are less than or equal to 100. Then n + m
lines representing the coordinates of points follow. Each line contains two integers xi and yi
separated by a space, where (xi , yi ) represents the x-coordinate and the y-coordinate of the i-th
point. The color of the i-th point is black for 1 ≤ i ≤ n, and is white for n + 1 ≤ i ≤ n + m.

All the points have integral x- and y-coordinate values between 0 and 10000 inclusive. You can
also assume that no two points have the same position.

The end of the input is indicated by a line containing two zeros separated by a space.

Output

For each dataset, output "YES" if there exists a line satisfying the condition. If not, output
"NO". In either case, print it in one line for each input dataset.

Sample Input

3 3
100 700
200 200
600 600
500 100
500 300
800 500
3 3
100 300
400 600
400 100
600 400
500 900
300 300
3 4
300 300
500 300
400 600
100 100
200 900
500 900
800 100
1 2
300 300
100 100
500 500
1 1
100 100
200 100
2 2
0 0
500 700
1000 1400
1500 2100
2 2
0 0
1000 1000
1000 0
0 1000
3 3
0 100
4999 102
10000 103
5001 102
10000 102
0 101
3 3
100 100
200 100
100 200
0 0
400 0
0 400
3 3
2813 1640
2583 2892
2967 1916
541 3562
9298 3686
7443 7921
0 0

Output for the Sample Input

YES
NO
NO
NO
YES
YES
NO
NO
NO
YES


import java.util.*;
import static java.lang.System.*;

public class Main {

	Scanner sc = new Scanner(in);

	Map<String, Set<String>> map = new HashMap<String, Set<String>>();
	List<String> remove = new ArrayList<String>();
	List<String> add = new ArrayList<String>();
	Set<String> checked = new HashSet<String>();

	void calc(String s) {
		checked.add(s);
		Set<String> set = map.get(s);
		add.clear();
		remove.clear();
		for (String t : set) {
			if (map.containsKey(t)) {
				if (!checked.contains(t))
					calc(t);
				remove.add(t);
				for (String u : map.get(t))
					add.add(u);
			}
		}
		set.removeAll(remove);
		set.addAll(add);
	}

	void run() {
		while (true) {
			int n = sc.nextInt();
			if (n == 0) break;
			map.clear();
			String zero = null;
			for (int i = 0; i < n; i++) {
				StringTokenizer st = new StringTokenizer(sc.next(), ": ,.");
				Set<String> set = new HashSet<String>();
				String s = st.nextToken();
				map.put(s, set);
				if (i == 0) zero = s;
				while (st.hasMoreTokens())
					set.add(st.nextToken());
			}
			checked.clear();
			calc(zero);
			out.println(map.get(zero).size());
		}
	}

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

}

Problem A: Membership Management

Peter is a senior manager of Agile Change Management (ACM) Inc., where each employee is a member of one or more task groups. Since ACM is agile, task groups are often reorganized and their members frequently change, so membership management is his constant headache.

Peter updates the membership information whenever any changes occur: for instance, the following line written by him means that Carol and Alice are the members of the Design Group.

design:carol,alice.

The name preceding the colon is the group name and the names following it specify its members.

A smaller task group may be included in a larger one. So, a group name can appear as a member of another group, for instance, as follows.

development:alice,bob,design,eve.

Simply unfolding the design above gives the following membership specification, which is equivalent to the original.

development:alice,bob,carol,alice,eve.

In this case, however, alice occurs twice. After removing one of the duplicates, we have the following more concise specification.

development:alice,bob,carol,eve.

Your mission in this problem is to write a program that, given group specifications, identifies group members.

Note that Peter's specifications can include deeply nested groups. In the following, for instance, the group one contains a single member dave.

one:another.
another:yetanother.
yetanother:dave.

Input

The input is a sequence of datasets, each being in the following format.

n

group1:member1,1,...,member1,m1.

.

.

.

groupi:memberi,1,...,memberi,mi.

.

.

.

groupn:membern,1,...,membern,mn.

The first line contains n, which represents the number of groups and is a positive integer no more than 100. Each of the following n lines contains the membership information of a group: groupi (1 ≤ i ≤ n) is the name of the i-th task group and is followed by a colon (:) and then the list of its mi member s that are delimited by a comma (,) and terminated by a period (.).

Those group names are mutually different. Each mi (1 ≤ i ≤ n) is between 1 and 10, inclusive. A member is another group name if it is one of group1, group2,..., or groupn. Otherwise it is an employee name.

There are no circular (or recursive) definitions of group(s). You may assume that mi member names of a group are mutually different.

Each group or employee name is a non-empty character string of length between 1 and 15, inclusive, and consists of lowercase letters.

The end of the input is indicated by a line containing a zero.

Output

For each dataset, output the number of employees included in the first group of the dataset, that is group1, in a line. No extra characters should occur in the output.

Sample Input

2
development:alice,bob,design,eve.
design:carol,alice.
3
one:another.
another:yetanother.
yetanother:dave.
3
friends:alice,bob,bestfriends,carol,fran,badcompany.
bestfriends:eve,alice.
badcompany:dave,carol.
5
a:b,c,d,e.
b:c,d,e,f.
c:d,e,f,g.
d:e,f,g,h.
e:f,g,h,i.
4
aa:bb.
cc:dd,ee.
ff:gg.
bb:cc.
0

Output for the Sample Input

4
1
6
4
2


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

import static java.lang.Integer.parseInt;

/**
 * Miscalculation
 */
public class Main {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String line;
		String[] words;

		String exp = br.readLine();
		int ans = parseInt(br.readLine());

		int M, L;
		M = M(exp);
		L = L(exp);
		if (ans == M && ans == L) {
			System.out.println('U');
		} else if (ans == M) {
			System.out.println('M');
		} else if (ans == L) {
			System.out.println('L');
		} else {
			System.out.println('I');
		}
	}

	static int M(String exp) {
		char[] pri = new char[127];
		Arrays.fill(pri, (char) 3);
		pri['*'] = 2;
		pri['+'] = 1;
		pri[0] = 0;
		return calc(exp, pri);
	}

	static int L(String exp) {
		char[] pri = new char[127];
		Arrays.fill(pri, (char) 3);
		pri['*'] = 1;
		pri['+'] = 1;
		pri[0] = 0;
		return calc(exp, pri);
	}

	static int calc(String exp, char[] pri) {
		Deque<Character> stack = new ArrayDeque<>();
		Deque<Character> queue = new ArrayDeque<>();

		stack.push('\0');
		for (char c : exp.toCharArray()) {
			if (pri[c] > pri[stack.peek()]) {
				stack.push(c);
			} else {
				while (pri[c] <= pri[stack.peek()]) {
					queue.offer(stack.pop());
				}
				stack.push(c);
			}
		}
		while (stack.peek() != '\0') queue.offer(stack.pop());

		//
		String rpn = "";
		Deque<Integer> ans = new ArrayDeque<>();

		for (char c : queue) rpn += String.valueOf(c);
		for (char c : rpn.toCharArray()) {
			int a, b;
			switch (c) {
				case '*':
					b = ans.pop();
					a = ans.pop();
					ans.push(a * b);
					break;
				case '+':
					b = ans.pop();
					a = ans.pop();
					ans.push(a + b);
					break;
				default:
					ans.push(c - '0');
					break;
			}
		}
		return ans.peek();
	}
}

MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Problem B:
Miscalculation

Bob is an elementary schoolboy, not so good at mathematics. He found Father's calculator and tried cheating on his homework using it. His homework was calculating given expressions containing multiplications and additions. Multiplications should be done prior to additions, of course, but the calculator evaluates the expression from left to right, neglecting the operator precedence. So his answers may be the result of either of the following two calculation rules.

Doing multiplication before addition

Doing calculation from left to right neglecting the operator precedence

Write a program that tells which of the rules is applied from an expression and his answer.

An expression consists of integers and operators. All the integers have only one digit, from 0 to 9. There are two kinds of operators + and *, which represent addition and multiplication, respectively.

The following is an example expression.

1+2*3+4

Calculating this expression with the multiplication-first rule, the answer is 11, as in Sample Input 1. With the left-to-right rule, however, the answer will be 13 as shown in Sample Input 2.

There may be cases in which both rules lead to the same result and you cannot tell which of the rules is applied. Moreover, Bob sometimes commits miscalculations. When neither rules would result in Bob’s answer, it is clear that he actually did.

Input

The input consists of a single test case specified with two lines. The first line contains the expression to be calculated. The number of characters of the expression is always odd and less than or equal to 17. Each of the odd-numbered characters in the expression is a digit from '0' to '9'. Each of the even-numbered characters is an operator '+' or '*'. The second line contains an integer which ranges from 0 to 999999999, inclusive. This integer represents Bob's answer for the expression given in the first line.

Output

Output one of the following four characters:

M     When only the multiplication-first rule results Bob's answer.

L     When only the left-to-right rule results Bob's answer.

U     When both of the rules result Bob's answer.

I     When neither of the rules results Bob's answer.

Sample Input 1

1+2*3+4
11

Sample Output 1

M

Sample Input 2

1+2*3+4
13

Sample Output 2

L

Sample Input 3

3
3

Sample Output 3

U

Sample Input 4

1+2*3+4
9

Sample Output 4

I


import java.math.*;
import java.io.*;

class Main
{

    public static void main(String args[])throws IOException
    {
	BigInteger a = new BigInteger("1");
	for(int i=2;i<=1501;i++)
	    a = a.multiply(new BigInteger(Integer.toString(i)));
	BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	a = a.add(new BigInteger("1501"));
	int n = Integer.parseInt(in.readLine());
	System.out.println(a);
	for(int i=1501;i<n+1501;i++)
	    System.out.println(i);

    }

}

Problem D : Numbers

n が与えられるので、n 個の連続した正の整数を求めよ。
ただしすべての数が、１とその数自身以外の約数をもたなくてはならない。

Input

入力は以下のフォーマットで与えられる。

n

入力は以下の制約を満たす。

1 ≤ n ≤ 1,500

Output

最初の行に、あなたが選んだ連続したn 個の正の整数の中で一番小さいものを出力せよ。

2行目からn+1 行目に、それぞれの値に対する約数を出力せよ。

約数は1かその数自身でなければどの値を出力しても良い。

1行目に出力した数をxとして、i行目には x+i-2 の約数を出力せよ。

出力する値は5,000桁を超えてはいけない。

Sample Input 1

2

Sample Output 1

8
2
3

Sample Input 2

3

Sample Output 2

8
2
3
5

Hint

Sample Output 2では、8,9,10を3個の連続した整数として選んでいる。

2行目に、8の約数として2,3行目は9の約数として3,４行目には10の約数として5,を出力している。