import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class Main {

	void run() {

		Scanner in = new Scanner(System.in);

		while(true) {

			int N = Integer.parseInt(in.next());

			if (N == 0) break;

			List<String> wordList = new ArrayList<String>();

			for(int i = 0; i < N; i++) {
				String word = in.next();
				wordList.add(word.substring(0, 1));
				wordList.add(word.substring(word.length() - 1, word.length()));
			}

			Collections.sort(wordList);

			if(check(wordList)) {
				System.out.println("OK");
			} else {
				System.out.println("NG");
			}
		}
	}

	boolean check(List<String> wordList) {

		int count = 1;
		String word1 = wordList.get(0);
		for(int i = 1; i < wordList.size(); i++) {
			String word2 = wordList.get(i);
			if(word1.equals(word2)) {
				count++;
			} else {
				if(count == 2 || count % 2 != 0) return false;
				word1 = word2;
				count = 1;
			}
		}
		return true;
	}

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

こぶたぬきつねこ

A子さんの家に親戚のB男君がやってきました。彼は3歳で歌が大好きです。彼は幼稚園でならった「こぶたぬきつねこ」(山本直純作詞・作曲)という歌を一生懸命に歌っています。この歌では、4つのことば「こぶた」 「たぬき」 「きつね」「ねこ」が順にしりとりになっていて、さらに最後の音と最初の音が同じになっています。B男君は、A子さんに、同じようなしりとりが、B男君が言った単語から作れるか教えて欲しいと言われました。

そこで、A子さんを助けるために、与えられた単語から、その単語をすべて使って、順にしりとりをつくり、その上で、 第1 の単語の最初の文字と最終の単語の最後の文字が同じであるようにできるか否かを判定するプログラムを作成しましょう。

n 個の単語を入力とし、それらの単語の組からしりとりを作成できるか否かを判定し、可能な場合はOK と、不可能な場合は NG と出力するプログラムを作成してください。

Input

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

n
word1
word2
:
wordn

1 行目に単語の個数 n (2 ≤ n ≤ 10000) が与えられます。続く n 行に n 個の単語 wordi (32 文字以下の半角英小文字だけからなる文字列) が与えられます。

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

Output

入力データセットごとに、判定結果を１行に出力します。

Sample Input

5
apple
yellow
georgia
king
email
7
apple
yellow
georgia
king
email
wink
lucky
0

Output for the Sample Input

NG
OK


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Scanner;

public class Main {

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

		while(true){
			final int n = sc.nextInt();
			final int m = sc.nextInt();

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

			LinkedList<Integer> list = new LinkedList<Integer>();

			for(int i = 0; i < n; i++){
				list.add(sc.nextInt());
			}

			Collections.sort(list);
			Collections.reverse(list);

			int cost = 0;

			while(list.size() >= m){
				for(int i = 0; i < (m - 1); i++){
					cost += list.poll();
				}
				list.poll();
			}

			if(!list.isEmpty()){
				for(int i : list){
					cost += i;
				}
			}

			System.out.println(cost);
		}

	}
}

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

お客様大感謝祭

悪天候が続き野菜の価格が高騰する中、セブンマートではお客様に野菜のまとめ買いセールを実施しています。 日ごろなかなか店頭に並ばない野菜もお手頃価格で手に入るとあって、 店内はとても賑わっています。

ある日、松長団地に住む仲良し 3 人組がセブンマートの広告を手に話に花を咲かせていました。今回のセールは「お客様大感謝祭」と銘打っただけに、袋詰めした野菜の中で最も安いものが無料になるのが目玉となっています。広告を読んでみると、どうやら以下のようなセールのようです。

1 つの袋には m 個まで野菜を詰められる。

野菜が m 個詰めてある袋については、その中で最も安い野菜が無料となる。

野菜の個数が m 個に達しない袋は割引の対象外。

3人は早速セブンマートへ買い物に行きました。

買い物が終わり、 お店の外で待ち合わせた 3 人は安くてたくさん購入できたことに満足した様子で話をしていると、どうやら 3 人とも同じ野菜を購入していたことが分かりました。ある一人が、「本当に安いわよねぇ。これでXXX円だもの!」と言うと、もう一人は、「え?私はそれより**円高かったわ!どうして?」と驚き、また、残りの一人はレシートを見て自分が一番安く購入したことに気付きました。

さて、どのように袋詰めすれば購入価格を一番安くできるでしょうか。 購入する野菜の個数、袋に入る野菜の個数、各野菜の値段を入力とし、最低購入価格を出力するプログラムを作成してください。

Input

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

n m
p1 p2 ... pn

1 行目に購入する野菜の個数 n (1 ≤ n ≤ 1000) と袋に入る野菜の個数 m (1 ≤ m ≤ 1000)　が与えられます。２行目に各野菜の値段 pi (10 ≤ pi ≤ 10000) が与えられます。

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

Output

入力データセットごとに、最低購入価格を１行に出力します。

Sample Input

4 2
50 40 100 80
7 3
400 300 100 700 200 600 500
0 0

Output for the Sample Input

150
2100

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.util.*;

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[][] map = new int[n+1][4];
			for(int i=0;i<=n;i++){
				for(int j=0;j<4;j++){
					map[i][j] = sc.nextInt();
				}
			}

			boolean out = true;
			boolean flag = true;
			for(int i=0;i<n;i++){
				flag = true;
				if(map[i][1]>map[n][0]) flag = false;
				else if(map[i][2]>map[n][1]) flag = false;
				else if(map[i][3]>map[n][2]) flag = false;
				else if(map[i][1]*4+map[i][2]*9+map[i][3]*4>map[n][3]) flag = false;
				if(flag==true){
					System.out.println(map[i][0]);
					out = false;
				}
			}
			if(out==true) System.out.println("NA");
		}
	}
}

カロリー計算

食べ物には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.*;

public class Main {
  // constant

  static final int MAX_INT = (1 << 30);

  // inner classes

  static class State {
    int id, rem;

    State(int id, int rem) {
      this.id = id;
      this.rem = rem;
    }
  }

  // main
  public static final void main(String[] args) throws Exception {
    Scanner sc = new Scanner(System.in);

    while (true) {
      int n = sc.nextInt();
      int m = sc.nextInt();
      if (n == 0 && m == 0) break;

      int[][] edges = new int[n][n];
      for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++) edges[i][j] = 0;

      for (int i = 0; i < m; i++) {
        int a = sc.nextInt() - 1;
        int b = sc.nextInt() - 1;
        int c = sc.nextInt();

        edges[a][b] = edges[b][a] = c;
      }

      int start = 0;
      int goal = n - 1;

      int[][] dists = new int[n][3];
      boolean[][] used = new boolean[n][3];

      for (int i = 0; i < n; i++)
        for (int j = 0; j < 3; j++) {
          dists[i][j] = MAX_INT;
          used[i][j] = false;
        }

      dists[start][2] = 0;
      used[start][2] = true;

      ArrayList<State> q = new ArrayList<State>();
      q.add(new State(start, 2));

      while (! q.isEmpty()) {
        State u = q.get(0);
        int du = dists[u.id][u.rem];

        for (int i = 1; i < q.size(); i++) {
          State ui = q.get(i);
          if (du > dists[ui.id][ui.rem]) {
            u = ui;
            du = dists[ui.id][ui.rem];
          }
        }

        q.remove(u);

        int uid = u.id;
        int urem = u.rem;

        if (uid == goal) continue;

        for (int vid = 0; vid < n; vid++) {
          if (edges[uid][vid] == 0) continue;

          if (urem != 1 &&
              dists[vid][urem] > dists[uid][urem] + edges[uid][vid]) {
            dists[vid][urem] = dists[uid][urem] + edges[uid][vid];
            if (! used[vid][urem]) {
              used[vid][urem] = true;
              q.add(new State(vid, urem));
            }
          }

          if (urem > 0 && dists[vid][urem - 1] > dists[uid][urem]) {
            int vrem = urem - 1;
            dists[vid][vrem] = dists[uid][urem];
            if (! used[vid][vrem]) {
              used[vid][vrem] = true;
              q.add(new State(vid, vrem));
            }
          }
        }
      }

      int d0 = dists[goal][0];
      int d2 = dists[goal][2];

      System.out.println(d0 < d2 ? d0 : d2);
    }
  }
}

温泉旅行

温泉好きのたけしさんは、次の長期休暇を利用してとある温泉地への旅行を計画しています。移動は長距離バスを乗り継ぎ、なるべくお金をかけずに目的地へたどり着きたいと思っています。貯金があるとはいえ、資金に心許ないたけしさんは、おじいさんに相談することにしました。計画を聞いて感心したおじいさんは、たけしさんに特別な切符を渡しました。

その切符は、長距離バスの連続した2区間を1回だけ無料で乗れるというものでした。使いようによってはかなりの移動費削減が見込めますが、より大きな効果を発揮させるためにはしっかりした計画を練る必要があります。

出発地と目的地、及び中継地点が合わせて n 個、2つの地点を結ぶ路線が m 個与えられます。各地点にはそれぞれ 1 から n までの数字が割り振られています。出発地は 1、目的地は n です。路線の情報は、その路線が結ぶ2つの地点 a と b、及びその料金 c で表されます。特別な切符の効力により、任意の地点から、一度だけ連続した2つの路線を料金0で通過することができます。ただし、途中で目的地を通過しても、目的地にたどり着いたことにはなりません。

出発地、目的地、及び中継地点の総数 n と路線の数 m、各路線の情報を入力とし、料金の最小値を出力するプログラムを作成してください。ただし、必ず出発地から目的地へと到達する経路が存在するものとします。

入力

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

n m
a1 b1 c1
a2 b2 c2
:
am bm cm

1行目に出発地、目的地、及び中継地点の総数 n (2 ≤ n ≤ 100)と路線の数 m (1 ≤ m ≤ 300)が与えられます。続く m 行に各路線の情報 ai, bi, ci (1 ≤ ci ≤ 1000) が与えられます。

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

出力

入力データセットごとに、料金の最小値を1行に出力します。

入力例

2 1
1 2 5
3 2
1 2 5
2 3 5
6 9
1 2 7
1 3 9
1 5 14
2 3 10
2 4 15
3 4 11
3 5 2
4 5 9
4 6 8
0 0

出力例

5
0
7


import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

//Ice Maze
public class Main{

	int w, h, si, sj, gi, gj, INF = 1<<29, res;
	int[][] d = {{-1,0},{0,1},{1,0},{0,-1}};
	int[] ice, hit;
	int[][] id, dist;
	char[][] m;
	boolean[][] v;

	void mark(int i, int j, int x){
		id[i][j] = x;
		ice[x]++;
		for(int k=0;k<4;k++){
			int ni = i+d[k][0], nj = j+d[k][1];
			if(m[ni][nj]=='X'&&id[ni][nj]==0)mark(ni, nj, x);
		}
	}

	void f(int i, int j, int depth){
		if(res<=depth+dist[i][j])return;
		if(res<=depth+Math.abs(gi-i)+Math.abs(gj-j))return;
		if(gi==i && gj==j){
			res = Math.min(res, depth); return;
		}
		int c = 0;
		for(int k=0;k<4;k++){
			int ni = i+d[k][0], nj = j+d[k][1];
			if(v[ni][nj])c++;
		}
		if(2 <= c)return;
		for(int k=0;k<4;k++){
			int ni = i+d[k][0], nj = j+d[k][1];
			if(!v[ni][nj]&&m[ni][nj]!='#'){
				if(ice[id[ni][nj]]>>1 >= hit[id[ni][nj]]+1){
					hit[id[ni][nj]]++;
					v[ni][nj] = true;
					f(ni, nj, depth+1);
					v[ni][nj] = false;
					hit[id[ni][nj]]--;
				}
			}
		}
	}

	void run(){
		Scanner sc = new Scanner(System.in);
		ice = new int[144];
		hit = new int[144];
		dist = new int[14][14];
		m = new char[14][14];
		v = new boolean[14][14];
		for(;;){
			w = sc.nextInt(); h = sc.nextInt();
			if((w|h)==0)break;
			for(int i=0;i<h+2;i++)for(int j=0;j<w+2;j++){
				dist[i][j] = INF;
				v[i][j] = false;
				m[i][j] = '#';
			}
			for(int i=1;i<=h;i++){
				char[] c = sc.next().toCharArray();
				for(int j=1;j<=w;j++){
					m[i][j] = c[j-1];
					if(m[i][j]=='S'){
						m[i][j] = '.'; si = i; sj = j;
					}
					if(m[i][j]=='G'){
						m[i][j] = '.'; gi = i; gj = j;
					}
				}
			}
			Arrays.fill(ice, 0);
			ice[0] = INF;
			id = new int[h+2][w+2];
			int ID = 1;
			for(int i=1;i<=h;i++)for(int j=1;j<=w;j++){
				if(m[i][j]!='X'||id[i][j]>0)continue;
				mark(i, j, ID);
				if(ice[ID]==1){
					m[i][j] = '#';
				}
				ID++;
			}
			dist[gi][gj] = 0;
			Queue<int[]> que = new LinkedList<int[]>();
			que.add(new int[]{gi, gj});
			while(!que.isEmpty()){
				int V[] = que.poll();
				int pi = V[0], pj = V[1];
				for(int k=0;k<4;k++){
					int ni = pi+d[k][0], nj = pj+d[k][1];
					if(m[ni][nj]!='#'&&dist[ni][nj]==INF){
						dist[ni][nj] = dist[pi][pj]+1;
						que.add(new int[]{ni, nj});
					}
				}
			}
			res = INF;
			Arrays.fill(hit, 0);
			v[si][sj] = true;
			f(si, sj, 0);
			System.out.println(res);
		}
	}

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

氷の迷路

四角のマスを縦横にならべた長方形の迷路があります。この迷路では東西南北の隣接するマスへ移動しながら、スタートのマスSを出発し、ゴールのマスGを目指します。マスの種類には、平原、山、氷の３種類があります。SとGは、平原のマスに置かれています。平原のマスには移動できますが、山のマスには移動できません。氷のマスは移動できますが、条件によって氷が割れ動けなくなります。

氷のマスは東西南北に隣接するもの全体でひとつの塊として扱われます。

氷の塊のなかで、マスの個数の半分より多くのマスに移動すると、塊全体が割れます。

例えば、図１は与えられた迷路の最短経路のステップ数が 11 であることを示しています。

図1

しかし、図２のように氷のマスを通って近道をしようとすると、大きさが６の氷の塊に対する４回目の移動後に動けなくなってしまいGには到達できません。

図2

このような迷路の情報を入力とし、SからGまでの最短経路のステップ数を求めるプログラムを作成してください。マスの種類はそれぞれ以下の文字で表されます：

文字（半角）

マスの種類

. （ピリオド）

平原

#（シャープ）

山

X

氷

与えられる迷路は必ず解けるものとします。迷路はその東西方向のマスの数 X、南北方向のマスの数 Y と X × Y 個の文字として与えられます。

入力

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

X Y
line1
line2
:
lineY

1行目に迷路の大きさを表す整数 X, Y (2 ≤ X, Y ≤ 12) が与えられます。続く Y 行に迷路の i 行目の情報 linei (長さ X の半角英文字列) が与えられます。

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

出力

データセットごとに、最小のステップ数を１行に出力します。

入力例

5 5
.X.S.
.X#..
.XX##
.#XG.
..X..
7 3
SXX.XXG
X.#.#X.
XXX.XX#
4 4
S...
X.X.
GX..
...X
10 10
..XXXXX.XX
.X.#.#X.XX
SX.#X.X..X
#X.##.X.XX
..XXXX#.XX
##.##.##XX
....X.XX#X
.##X..#X#X
....XX#..X
...#XXG..X
0 0

出力例

11
10
10
33


import java.util.Scanner;
public class Main {
public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int c1 = sc.nextInt();
		int c5 = sc.nextInt()*5;
		int c10 = sc.nextInt()*10;
		int c50 = sc.nextInt()*50;
		int c100 = sc.nextInt()*100;
		int c500 = sc.nextInt()*500;
		if(c1+c5+c10+c50+c100+c500>=1000){
			System.out.println(1);
		}else{
			System.out.println(0);
		}
	}

}

お財布メタボ診断

４月に消費税が８％になってから、お財布が硬貨でパンパンになっていませんか。同じ金額を持ち歩くなら硬貨の枚数を少なくしたいですよね。硬貨の合計が１０００円以上なら、硬貨をお札に両替して、お財布のメタボ状態を解消できます。

お財布の中の硬貨の枚数が種類ごとに与えられたとき、硬貨をお札に両替できるかどうかを判定するプログラムを作成してください。

入力

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

c1 c5 c10 c50 c100 c500

入力は１行からなる。c1、c5、c10、c50、c100、c500 (0 ≤ c1, c5, c10, c50, c100, c500 ≤ 50) は、それぞれ、1円、5円、10円、50円、100円、500円硬貨の枚数を表す。

出力

硬貨をお札に両替できるなら1 を、そうでなければ 0 を１行に出力する。

入出力例

入力例１

3 1 4 0 4 1

出力例１

0

入力例２

2 1 4 3 2 3

出力例２

1

入力例３

21 5 9 3 1 1

出力例３

0

入力例４

2 4 3 3 3 1

出力例４

1

入力例５

50 50 50 4 0 0

出力例５

1


import java.util.Scanner;

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

		int n = sc.nextInt();
		int[] k = new int[n];
		int[] p = new int[n];

		for (int i = 0; i < n; i++){
			k[i] = sc.nextInt();
			p[i] = sc.nextInt();
		}

		for (int i = 0; i < n; i++){
			int res = k[i] % p[i];
			if (res == 0){
				res = p[i];
			}

			System.out.println(res);
		}
	}
}

残り物には福がある

K 個の石から、P 人が順番に１つずつ石を取るゲームがあります。P 人目が石を取った時点で、まだ石が残っていれば、また１人目から順番に１つずつ石を取っていきます。このゲームでは、最後の石を取った人が勝ちとなります。K とP が与えられたとき、何人目が勝つか判定するプログラムを作成してください。

入力

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

N
K1 P1
K2 P2
:
KN PN

１行目にはゲームを行う回数 N (1 ≤ N ≤ 100) が与えられる。続く N 行に、i 回目のゲームにおける石の個数 Ki (2 ≤ Ki ≤ 1000) と、ゲームに参加する人数 Pi (2 ≤ Pi ≤ 1000) が与えられる。

出力

それぞれのゲームについて、何人目が勝つかを１行に出力する。

入出力例

入力例

3
10 3
2 10
4 2

出力例

1
2
2


import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.NoSuchElementException;

public class Main {

	public static void main(String[] args) {
		FastScanner sc = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		int n = sc.nextInt();
		for (int i = 0; i < n; i++) {
			int k = sc.nextInt();
			int p = sc.nextInt();
			int a = k % p;
			out.println(a == 0 ? p : a);
		}
		out.flush();
	}

}

class FastScanner {
	private final InputStream in = System.in;
	private final byte[] buffer = new byte[1024];
	private int ptr = 0;
	private int buflen = 0;

	private boolean hasNextByte() {
		if (ptr < buflen) {
			return true;
		} else {
			ptr = 0;
			try {
				buflen = in.read(buffer);
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (buflen <= 0) { return false; }
		}
		return true;
	}

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

	private boolean isPrintableChar(int c) {
		return '!' <= c && c <= '~';
	}

	private void skipUnprintable() {
		while (hasNextByte() && !isPrintableChar(buffer[ptr])) {
			ptr++;
		}
	}

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

	public int nextInt() {
		if (!hasNext()) { throw new NoSuchElementException(); }
		int n = 0;
		boolean minus = false;
		byte b = readByte();
		if (b == '-') {
			minus = true;
			b = readByte();
		}
		if (b < '0' || '9' < b) { throw new NumberFormatException(); }
		while (true) {
			if ('0' <= b && b <= '9') {
				n *= 10;
				n += b - '0';
			} else if (b == -1 || !isPrintableChar(b)) {
				return minus ? -n : n;
			} else {
				throw new NumberFormatException();
			}
			b = readByte();
		}
	}
}


import java.util.Scanner;

class Main{
    public static void main(String[ ] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        System.out.println(n*32);
    }
}

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

ワード

コンピュータで扱われるデータの最小単位をビット(bit)と呼び、複数のビットをまとめて表した情報量をワード(word)と呼びます。現在、多くのコンピュータでは１ワードを３２ビットとして処理しています。

１ワードを３２ビットで表すコンピュータについて、ワード単位で与えられたデータ量 W をビット単位で出力するプログラムを作成せよ。

Input

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

W

入力は１行からなり、データ量 W (0 ≤ W ≤ 100) が与えられる。

Output

ビット単位の値を１行に出力する。

Sample Input 1

4

Sample Output 1

128

Sample Input 2

3

Sample Output 2

96


import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;

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

		int n = sc.nextInt();
		Map<Character, HashSet<Integer>> s = new HashMap<Character, HashSet<Integer>>();
		char[] t = new char[n];

		String ss = sc.next();
		for(int i = 0; i < n; i++) {
			char tmp = ss.charAt(i);

			if(!s.containsKey(tmp)) {
				s.put(tmp, new HashSet<Integer>());
			}

			s.get(tmp).add(i);
		}

		String st = sc.next();
		for(int i = 0; i < n; i++) {
			t[i] = st.charAt(i);
		}

		int[] table = new int[n];
		for(int i = 0;i < n; i++) {
			table[i] = 0;
		}
		table[0] = 1;

		for(int i = 1; i < n; i++) {
			for(int x : s.get(t[i])) {
				if(x < i) {
					table[i] += table[x];
				}
			}
		}

		System.out.println(table[n - 1]);
	}
}

Transporter

In the year 30XX, an expedition team reached a planet and found a warp machine suggesting the existence of a mysterious supercivilization. When you go through one of its entrance gates, you can instantaneously move to the exit irrespective of how far away it is. You can move even to the end of the universe at will with this technology!

The scientist team started examining the machine and successfully identified all the planets on which the entrances to the machine were located. Each of these N planets (identified by an index from $1$ to $N$) has an entrance to, and an exit from the warp machine. Each of the entrances and exits has a letter inscribed on it.

The mechanism of spatial mobility through the warp machine is as follows:

If you go into an entrance gate labeled with c, then you can exit from any gate with label c.

If you go into an entrance located on the $i$-th planet, then you can exit from any gate located on the $j$-th planet where $i < j$.

Once you have reached an exit of the warp machine on a planet, you can continue your journey by entering into the warp machine on the same planet. In this way, you can reach a faraway planet. Our human race has decided to dispatch an expedition to the star $N$, starting from Star $1$ and using the warp machine until it reaches Star $N$. To evaluate the possibility of successfully reaching the destination. it is highly desirable for us to know how many different routes are available for the expedition team to track.

Given information regarding the stars, make a program to enumerate the passages from Star $1$ to Star $N$.

Input

The input is given in the following format.

$N$
$s$
$t$

The first line provides the number of the stars on which the warp machine is located $N$ ($2 \leq N \leq 100,000$). The second line provides a string $s$ of length $N$, each component of which represents the letter inscribed on the entrance of the machine on the star. By the same token, the third line provides a string $t$ of length $N$ consisting of the letters inscribed on the exit of the machine. Two strings $s$ and $t$ consist all of lower-case alphabetical letters, and the $i$-th letter of these strings corresponds respectively to the entrance and exit of Star $i$ machine.

Output

Divide the number of possible routes from Star $1$ to Star $N$ obtained above by 1,000,000,007, and output the remainder.

Sample Input 1

6
abbaba
baabab

Sample Output 1

5

Sample Input 2

25
neihsokcpuziafoytisrevinu
universityofaizupckoshien

Sample Output 2

4


import java.util.*;

class Main{
 public static void main(String[]args){
  Scanner sc = new Scanner(System.in);
   int R = sc.nextInt();
   int B = sc.nextInt();
   int W = sc.nextInt();
   int G = sc.nextInt();

   System.out.println(R + B + W + G);
 }
}

柴犬の数

イヅア公園には、夕方になると柴犬と散歩する人たちがたくさん来ます。柴犬には毛の色によって赤柴、黒柴、白柴、胡麻柴という種類があります。柴犬がたくさんいるとうれしいトモエちゃんは、それぞれの毛色の柴犬が何頭いるかがんばって数えましたが、まだ足し算ができないので柴犬が全部で何頭いるかわかりません。

それぞれの毛色の柴犬の数が与えられたときに、柴犬の総数を計算するプログラムを作成せよ。

入力

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

$R$ $B$ $W$ $G$

１行に赤柴の数$R$ ($1 \leq R \leq 100$)、黒柴の数$B$ ($1 \leq B \leq 100$)、白柴の数$W$ ($1 \leq W \leq 100$)、胡麻柴の数$G$ ($1 \leq G \leq 100$)が与えられる。

出力

柴犬の総数を１行に出力する。

入出力例

入力例１

4 2 1 1

出力例１

8

入力例２

22 18 34 36

出力例２

110


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

public class Main {
	private StringTokenizer st;
	private BufferedReader bf;
	private int w;

	Main() {
		readData();

	}

	private void readData() {
		try {
			bf = new BufferedReader(new InputStreamReader(System.in));
			st = new StringTokenizer(bf.readLine());

			while (true) {
				int m = nextInt();
				if (m==0)
					break;
				boolean[] r = new boolean[256];
				char[] table = new char[256];
				for (int i=0;i<m;i++) {
					char a = next().charAt(0);
					char b = next().charAt(0);
					table[a] = b;
					r[a] = true;
				}

				int n = nextInt();
				String tmp;
				StringBuilder result = new StringBuilder();
				for (int i=0;i<n;i++) {
					tmp = next();
					char c = tmp.charAt(0);
					if (r[c]) {
						result.append(table[c]);
						r[c] = false;
						table[c] = c;
					} else {
						result.append(c);
					}
				}
				System.out.println(result.toString());
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	private String next() throws IOException {
		if (st == null || !st.hasMoreTokens())
			st = new StringTokenizer(bf.readLine());
		return st.nextToken();
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Main m = new Main();
	}

}

与えられた変換表にもとづき，データを変換するプログラムを作成しなさい．

データに使われている文字は英字か数字で，英字は大文字と小文字を区別する．変換表に現れる文字の順序に規則性はない．

変換表は空白をはさんで前と後ろの 2 つの文字がある(文字列ではない)．変換方法は，変換表のある行の前の文字がデータに現れたら，そのたびにその文字を後ろの文字に変換し出力する．変換は 1 度だけで，変換した文字がまた変換対象の文字になっても変換しない．変換表に現れない文字は変換せず，そのまま出力する．

入力ファイルには，変換表（最初の n + 1 行）に続き変換するデータ（n + 2 行目以降）が書いてある． 1 行目に変換表の行数 n，続く n 行の各行は，空白をはさんで 2 つの文字，さらに続けて， n + 2 行目に変換するデータの行数 m，続く m 行の各行は 1 文字である． m ≤ 105 とする．出力は，出力例のように途中に空白や改行は入れず 1 行とせよ．

入力例

3

A a

0 5

5 4

10

A

B

C

0

1

4

5

a

b

A

出力例

aBC5144aba

入力

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

出力

データセットごとに、変換後の文字列を１行に出力する．

入力例

3
A a
0 5
5 4
10
A
B
C
0
1
4
5
a
b
A
3
A a
0 5
5 4
10
A
B
C
0
1
4
5
a
b
A
0

出力例

aBC5144aba
aBC5144aba

各データセットの出力（変換後の文字列）の後に改行を入れること．

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


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

public class Main {

	static char[] in = new char[123];
	static char[] out = new char[123];

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

		initialize();
		int n = 0;
		while ((line = br.readLine()) != null) {
			if (n == 0) {
				if ((n = Integer.parseInt(line)) == 0)
					break;
			} else {
				if (line.contains(" ")) {
					in[line.charAt(0)] = line.charAt(0);
					out[line.charAt(0)] = line.charAt(2);
				} else {
					System.out.print(String.valueOf(out[line.charAt(0)]));
				}
				n--;
				if (n == 0 && line.length() == 1) {
					System.out.println();
					initialize();
				}
			}
		}
	}

	public static void initialize() {
		for (int i = 0; i < 123; i++) {
			in[i] = (char) i;
			out[i] = (char) i;
		}
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {

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

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

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

			//
			m++;
			int[] wish = new int[m];
			for (int i = 0; i < n; i++) {
				line = br.readLine();
				for (int j = 0; j < line.length(); j += 2) {
					if (line.charAt(j) == '1')
						wish[j / 2 + 1]++;
				}
			}

			//
			StringBuilder sb = new StringBuilder();
			for (int i = n; i >= 0; i--) {
				for (int j = 1; j < m; j++) {
					if (wish[j] == i)
						sb.append(j + " ");
				}
			}
			System.out.println(sb.toString().substring(0, sb.length() - 1));
		}
	}
}

ある学校で修学旅行へ行く計画がある.そのためにアンケート調査を行った.
生徒は 1 から n までの生徒番号を持ち,旅行候補の場所を 1 から m までの番号で表し,行きたい場所に ○,行きたくない場所に×の印をつけて提出している.

このとき, 行きたい場所の人数が多い順に,場所の番号を出力するプログラムを作成せよ.人数が同じときは,場所の番号順とする.

入力データ の 1 行目は生徒の人数 n と旅行候補の場所の数 m が空白で区切られ, i + 1 行に生徒 i のアンケート結果を ○ は 1 で×は 0 で表し,空白で区切られた m 個の数字が並んでいる.1 ≤ n ≤ 1000, 1 ≤ m ≤ 100 とする.

入力例１

4 6

1 0 1 0 1 1

1 1 0 1 0 0

1 1 1 0 0 0

1 0 1 0 1 0

出力例１

1 3 2 5 4 6

入力

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

出力

データセットごとに、場所の番号 を１行に出力する．

入力例

4 6
1 0 1 0 1 1
1 1 0 1 0 0
1 1 1 0 0 0
1 0 1 0 1 0
4 6
1 0 1 0 1 1
1 1 0 1 0 0
1 1 1 0 0 0
1 0 1 0 1 0
0 0

出力例

1 3 2 5 4 6
1 3 2 5 4 6

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


import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
import java.util.Set;

//String With Rings
public class Main{

	List<Integer>[] e;
	int res;
	boolean[] v;

	void dfs(int k, int d){
		res = Math.max(res, d);
		for(int x:e[k])if(!v[x]){
			v[x] = true;
			dfs(x, d+1);
			v[x] = false;
		}
	}

	@SuppressWarnings("unchecked")
	void run(){
		Scanner sc = new Scanner(System.in);
//		sc.nextInt();
//		long T = System.currentTimeMillis();
		Random rand = new Random(1334259171148L);
//		System.out.println(T);
		for(;;){
			int n = sc.nextInt();
			if(n==0)break;
			e = new List[101];
			for(int i=1;i<101;i++)e[i]=new ArrayList<Integer>();
			boolean[] u = new boolean[101];
			while(n--!=0){
				int a = sc.nextInt(), b = sc.nextInt();
				u[a] = u[b] = true;
				e[a].add(b); e[b].add(a);
			}
			v = new boolean[101];
			res = 0;
//			int min = 150, max = 0;
//			for(int i=1;i<101;i++)if(u[i]){
//				min = Math.min(min, e[i].size()); max = Math.max(max, e[i].size());
//			}
			int[] a = new int[100];
			int id = 0;
			for(int i=1;i<101;i++)if(!e[i].isEmpty())a[id++] = i;
			Set<Integer> U = new HashSet<Integer>();
			for(int i=0;i<id/2;i++){
				Arrays.fill(v, false);
				int s = rand.nextInt(id);
				while(U.contains(s))s = rand.nextInt(id);
				v[a[s]] = true;
				dfs(a[s], 1);
			}
//			for(int i=1;i<101;i++)if(u[i]){
//				Arrays.fill(v, false);
//				v[i] = true;
//				long S = System.currentTimeMillis();
//				dfs(i, 1);
//				System.out.println("S:"+i+" Time:"+(System.currentTimeMillis()-S)+" ms." + " RES:"+res);
//			}
			System.out.println(res);
		}
//		System.out.println((System.currentTimeMillis()-T)+" ms.");
	}

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

両端にリングのついた紐を考える.リングは正整数が付いていて,紐を区別する.紐の両端のリングには異なる数 a, b が付けられる.これを,[a, b] と記述する.複数の紐があり,一方の紐と他方の紐のリングに付いている数が同じ場合,そのリングのところで,これらの紐をつなげることができて,つなげてできたものを鎖と呼ぶことにする.例えば,[1, 3] と [3, 4] という紐からは [1, 3, 4] という鎖ができる.紐と鎖や鎖同志も同じ整数が付いているリングのところでつなげることができるものとする.

例えば,鎖 [1, 3, 4] と紐 [5, 1] からは [5, 1, 3, 4] ができ,鎖 [1, 3, 4] と鎖 [2, 3, 5] からは, 中央でクロスしたような形になる.鎖 [1, 3, 4] と鎖 [4, 6, 1] からは, 輪の形ができる.

このように様々な形ができるが, そのうちの一部で,同じ数の付いたリングは一度だけたどるつながった複数の紐を鎖と呼ぶことにする.例えば,鎖 [1, 3, 4] と鎖[2, 3, 5] からできる,中央でクロスしたような形には, [1, 3, 5],[2, 3, 4] という鎖も含まれ,鎖 [1, 3, 4] と鎖 [4, 6, 1] からできる輪には, [1, 3, 4, 6],[3, 4, 6, 1],[4, 6, 1, 3]などの鎖が含まれる.

これらの鎖に対して,含まれる数の個数を長さと定義する. 与えられた複数の紐に対して,つなげられるものはすべてつなげると1つ以上の
鎖を含む形ができる.そのうちの最大の鎖の長さを求めるプログラムを作成せよ.

入力データ の最初の行には紐の個数である正整数 1 ≤ n ≤ 100 が書いてあり,つづく n 行のそれぞれには, 空白で区切られた 2 つの整数 a, b が書いてあり 1 ≤ a < b ≤ 100 となっている.各行の 2 つの整数は 1 つの紐の両端の整数を表わす.

入力例１

入力例２

入力例３

7

6

7

1 3

1 2

1 3

3 4

2 3

2 4

1 4

3 4

3 5

2 7

4 5

4 6

5 7

1 5

6 7

6 7

2 6

2 6

1 7

4 7

出力例１

出力例２

出力例３

5

6

4

入力

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

出力

データセットごとに、最大の鎖の長さを１行に出力する．

入力例

7
1 3
3 4
1 4
2 7
5 7
6 7
1 7
6
1 2
2 3
3 4
4 5
1 5
2 6
7
1 3
2 4
3 5
4 6
6 7
2 6
4 7
0

出力例

5
6
4

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


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
	 public static void main (String[] args) throws IOException	{
		 InputStreamReader is = new InputStreamReader(System.in);
		 BufferedReader br = new BufferedReader(is);
		 String str= br.readLine();
	     int cnt=0,cnt1=0;
	     for(int i=0;i<str.length()-2;i++){
	       	if(str.charAt(i)=='J'){
	       		if(str.charAt(i+1)=='O'){
	       			if(str.charAt(i+2)=='I'){
	       				cnt++;
	       			}
	       		}
	       	}
	       	if(str.charAt(i)=='I'){
	       		if(str.charAt(i+1)=='O'){
	       			if(str.charAt(i+2)=='I'){
	       				cnt1++;
	       			}
	       		}
	       	}
	   	}
	    System.out.println(cnt);
	    System.out.println(cnt1);
	}
}

JOIとIOI

問題

与えられた文字列内の連続する3文字が，JOIまたはIOIという並びになっている個所がそれぞれ何個所あるのかを数え上げるプログラムを作成せよ．文字列はアルファベットの大文字だけからなる．例えば下図の「JOIOIOI」という文字列にはJOIが1個所，IOIが2個所に含まれている．

入力

入力は複数のデータセットからなる．各データセットは1行であり，10000文字以下のアルファベットの大文字からなる．入力は EOF で終了する.

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

出力

データセットごとに, 1行目に見つかったJOIの個数，2行目に見つかったIOIの個数をそれぞれ出力せよ．

入出力例

入力例

JOIJOI
JOIOIOIOI
JOIOIJOINXNXJIOIOIOJ

出力例

2
0
1
3
2
3

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


import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.List;

public class Main{
	static StringBuilder out = new StringBuilder();
	static final String OK = "OK";
	static final String NG = "NG";
	static final String Possible = "Possible";
	static final String Impossible = "Impossible";
	static FastReader in = new FastReader();
	static final int HEADS = 1;
	static final int TAILS = 0;

	// static final int INF = Integer.MAX_VALUE - 300000000;

	public static void main(String[] args) {
		while (upsideDown())
			;
	}

	private static boolean upsideDown() {
		int h = in.nextInt();
		int w = in.nextInt();
		if (h == 0 && w == 0) return false;

		int[][] senbei = in.nextIntArray2D(h, w);

		System.out.println(solve(senbei));
		return true;
	}

	private static int solve(int[][] senbei) {
		int row = senbei.length;
		int line = senbei[0].length;
		int ex = (int) Math.pow(2, row);

		int[] score = new int[ex];

		for (int i = 0; i < line; i++) {
			for (int j = 0; j < ex; j++) {
				int tempScore = 0;
				int[] filter = makeFilter(row, j);
				for (int k = 0; k < row; k++) {
					tempScore += (senbei[k][i] + filter[k]) % 2;
				}
				score[j] += Math.max(tempScore, row - tempScore);
			}
		}

		int maxScore = 0;
		for (int i = 0; i < ex; i++) {
			maxScore = Math.max(maxScore, score[i]);
		}
		return maxScore;
	}

	private static int[] makeFilter(int row, int i) {
		int[] filter = new int[row];
		int temp = i;
		for (int j = 0; j < row; j++) {
			filter[j] = temp % 2;
			temp /= 2;
		}
		return filter;
	}

	static void printExit(Object msg) {
		System.out.println(msg);
		System.exit(0);
	}
}

class FastReader{
	private InputStream in = System.in;
	private byte[] buf = new byte[1024];
	private int charNum;
	private int charLen;
	private StringBuilder sb = new StringBuilder();

	public int read() {
		if (charLen == -1) throw new InputMismatchException();
		if (charNum >= charLen) {
			charNum = 0;
			try {
				charLen = in.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (charLen <= 0) return -1;
		}
		return buf[charNum++];
	}

	public String next() {
		int c = read();
		while (isWhitespace(c)) {
			c = read();
		}
		sb.setLength(0);
		do {
			sb.appendCodePoint(c);
			c = read();
		} while (!isWhitespace(c));
		return sb.toString();
	}

	public char[] nextCharArray() {
		return next().toCharArray();
	}

	public char[][] nextCharArray2d(int lines) {
		char[] first = nextCharArray();
		char[][] array = new char[lines][first.length];
		array[0] = first;
		for (int i = 1; i < lines; i++)
			array[i] = nextCharArray();
		return array;
	}

	public char[][] nextCharArray2d(int lines, int rows) {
		char[][] array = new char[lines][rows];
		for (int i = 0; i < lines; i++)
			array[i] = nextCharArray();
		return array;
	}

	public int nextInt() {
		return (int) nextLong();
	}

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

	public List<Integer> nextIntList(int n) {
		Integer[] array = new Integer[n];
		for (int i = 0; i < n; i++)
			array[i] = nextInt();
		return Arrays.asList(array);
	}

	public int[][] nextIntArray2D(int n, int m) {
		int[][] array = new int[n][m];
		for (int i = 0; i < n; i++)
			array[i] = nextIntArray(m);
		return array;
	}

	public List<int[]> nextIntsList(int n, int m) {
		List<int[]> list = new ArrayList<int[]>(n);
		for (int i = 0; i < n; i++)
			list.add(nextIntArray(m));
		return list;
	}

	public long nextLong() {
		int c = read();
		while (isWhitespace(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			if (c < '0' || c > '9') throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isWhitespace(c));
		return res * sgn;
	}

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

	public double[] nextDoubleArray(int n) {
		double[] array = new double[n];
		for (int i = 0; i < n; i++)
			array[i] = nextDouble();
		return array;
	}

	public boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}
}

おせんべい

問題

IOI製菓では，創業以来の伝統の製法で煎餅（せんべい）を焼いている．この伝統の製法は，炭火で一定時間表側を焼き，表側が焼けると裏返して，炭火で一定時間裏側を焼くというものである．この伝統を守りつつ，煎餅を機械で焼いている．この機械は縦 R (1 ≤ R ≤ 10) 行, 横 C (1 ≤ C ≤ 10000) 列の長方形状に煎餅を並べて焼く．通常は自動運転で，表側が焼けたら一斉に煎餅を裏返し裏側を焼く．

ある日，煎餅を焼いていると，煎餅を裏返す直前に地震が起こり何枚かの煎餅が裏返ってしまった．幸いなことに炭火の状態は適切なままであったが，これ以上表側を焼くと創業以来の伝統で定められている焼き時間を超えてしまい，煎餅の表側が焼けすぎて商品として出荷できなくなる．そこで，急いで機械をマニュアル操作に変更し，まだ裏返っていない煎餅だけを裏返そうとした．この機械は，横の行を何行か同時に裏返したり縦の列を何列か同時に裏返したりすることはできるが，残念なことに，煎餅を１枚ごと裏返すことはできない．

裏返すのに時間がかかると，地震で裏返らなかった煎餅の表側が焼けすぎて商品として出荷できなくなるので，横の何行かを同時に１回裏返し，引き続き，縦の何列かを同時に１回裏返して，表側を焼きすぎずに両面を焼くことのできる煎餅，つまり，「出荷できる煎餅」の枚数をなるべく多くすることにした．横の行を１行も裏返さない，あるいは，縦の列を１列も裏返さない場合も考えることにする．出荷できる煎餅の枚数の最大値を出力するプログラムを書きなさい．

地震の直後に，煎餅が次の図のような状態になったとする．黒い丸が表側が焼ける状態を，白い丸が裏側が焼ける状態を表している．

1行目を裏返すと次の図のような状態になる．

さらに， 1列目と5列目を裏返すと次の図のような状態になる．この状態では，出荷できる煎餅は9枚である．

ヒント

R の上限 10 は C の上限 10000 に比べて小さいことに注意せよ．

入力

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

入力の1行目には2つの整数 R, C (1 ≤ R ≤ 10, 1 ≤ C ≤ 10 000) が空白を区切りとして書かれている．続く R 行は地震直後の煎餅の状態を表す． (i+1) 行目 (1 ≤ i ≤ R) には， C 個の整数 ai,1, ai,2, ……, ai,C が空白を区切りとして書かれており， ai,j は i 行 j 列 の煎餅の状態を表している. ai,j が 1 なら表側が焼けることを， 0 なら裏側が焼けることを表す．

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

出力

データセットごとに，出荷できる煎餅の最大枚数を1行に出力する．

入出力例

入力例

2 5
0 1 0 1 0
1 0 0 0 1
3 6
1 0 0 0 1 0
1 1 1 0 1 0
1 0 1 1 0 1
0 0

出力例

9
15

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


import java.util.Scanner;

public class Main{
    public Main(){
	Scanner sc = new Scanner(System.in);

	while(sc.hasNext()){
	    String s = sc.next();
	    String t = sc.next();
	    s = " " + s;
	    t = " " + t;
	    int n = s.length();
	    int m = t.length();
	    int a[][] = new int[n+1][];
	    int b[][] = new int[n+1][];
	    a[0] = new int[m+1];
	    a[1] = new int[m+1];
	    b[0] = new int[m+1];
	    b[1] = new int[m+1];

	    for(int i = 1; i < n; i++){
		a[i+1] = new int[m+1];
		b[i+1] = new int[m+1];
		char w = s.charAt(i);

		for(int j = 1; j < m; j++){
		    if(w == t.charAt(j)){
			if(b[i][j] == 1){
			    a[i+1][j+1] = a[i][j] + 1;
			} else {
			    a[i+1][j+1] = 1;
			}
			b[i+1][j+1] = 1;
		    } else {
			if(a[i+1][j] > a[i][j+1]){
			    a[i+1][j+1] = a[i+1][j];
			} else {
			    a[i+1][j+1] = a[i][j+1];
			}
		    }
		}
	    }
	    int max = 0;
	    for(int i = 1; i <= m; i++){
		if(max < a[n][i]){
		    max = a[n][i];
		}
	    }
	    System.out.println(Integer.toString(max));
	}
    }

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

共通部分文字列

問題

2 個の文字列が与えられたとき, 両方の文字列に含まれる文字列のうち最も長いものを探し, その長さを答えるプログラムを作成せよ.

ここで, 文字列 s が文字列 t に含まれるとは, t の中に s が連続して現れることをいう. 空文字列, すなわち長さ 0 の文字列は, どんな文字列にも含まれる. 例えば, 文字列 ABRACADABRA には次の文字列が含まれる: ABRA, RAC, D, ACADABRA, ABRACADABRA,空文字列など. 一方, 文字列 ABRACADABRA には次の文字列は含まれない: ABRC, RAA,BA, K など.

例

例 1: 文字列として ABRACADABRA と ECADADABRBCRDARA が与えられた場合, 両方に含まれる文字列には CA や CADA や ADABR や空文字列などがある. そのうち最も長いのは ADABR であり, その長さは 5 である. 2 個の文字列の中に含まれる ADABR
の位置を以下に示す.

ABRACADABRA

ECADADABRBCRDARA

例 2: 文字列として UPWJCIRUCAXIIRGL と SBQNYBSBZDFNEV が与えられた場合, 両方に含まれる文字列は空文字列のみであり, その長さは 0 である.

入力

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

入力は 2 行からなり, 1 行目に 1 個目の文字列が, 2 行目に 2 個目の文字列が与えられる. 文字列は英大文字からなり, 各々の文字列の長さは 1 以上 4000 以下である.

採点用データのうち, 配点の 30% 分については, 各々の文字列の長さは 1 以上 50以下である.

入力の終わりは EOF で示される. データセットの数は 10 を超えない．

出力

データセットごとに与えられた 2 個の文字列の両方に含まれる文字列のうち最も長いものの長さを 1 行に出力する.

入出力例

入力例

ABRACADABRA
ECADADABRBCRDARA
UPWJCIRUCAXIIRGL
SBQNYBSBZDFNEV

出力例

5
0

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


import java.util.*;

public class Main {
	static class pair{
		int x,y;
		pair(int x,int y){
			this.x = x;
			this.y = y;
		}
	}
	static Queue<pair> q = new LinkedList<pair>();
	public static void main(String args[]){
		Scanner sc = new Scanner(System.in);
		int H = sc.nextInt(),W = sc.nextInt(),N = sc.nextInt();
		String temp_in;
		char[][] field = new char[H+2][W+2];
		pair start = null;
		for(int i=0;i<W+2;i++){
			field[0][i] = 'X';
			field[H+1][i] = 'X';
		}
		for(int i=0;i<H+2;i++){
			field[i][0] = 'X';
			field[i][W+1] = 'X';
		}
		int[][] dis = new int[H+2][W+2];
		int[][] check = new int[H+2][W+2];
		for(int i=1;i<H+1;i++){
			temp_in = sc.next();
			for(int j=1;j<W+1;j++){
				field[i][j] = temp_in.charAt(j-1);
				if(field[i][j] == 'S') {
					start = new pair(i,j);
				}
				dis[i][j] = -1;
				check[i][j] = 0;
			}
		}
		q.add(start);
		check[start.x][start.y] = 1;
		int[] dx = {1,0,-1,0};
		int[] dy = {0,1,0,-1};
		int level = 1, counter =0;
		while(!q.isEmpty()){
			pair p = q.poll();
			//System.out.println("size:"+q.size()+" level:"+level);
			int x = p.x, y = p.y;
			if(dis[x][y]==-1) dis[x][y] =0;

			String v_buf = String.valueOf(field[x][y]);
			if(Character.isDigit(field[x][y])&&Integer.parseInt(v_buf)<=level){
				//System.out.println(v);
				field[x][y] = '.';

				counter +=dis[x][y];
				if(level ==N) break;
				q.removeAll(q);
				for(int i=1;i<H+1;i++){
					for(int j=1;j<W+1;j++){
						dis[i][j] = -1;
						check[i][j] = 0;
 					}
				}
				pair new_p = new pair(x,y);
				check[x][y] = 1;
				q.add(new_p);
				level++;
			}else{
				for(int c=0;c<4;c++){
					if(field[x+dx[c]][y+dy[c]]!='X' && check[x+dx[c]][y+dy[c]]==0){
						dis[x+dx[c]][y+dy[c]]=dis[x][y]+1;
						pair temp_p = new pair(x+dx[c],y+dy[c]);
						q.add(temp_p);
						check[x+dx[c]][y+dy[c]] = 1;
					}
				}
			}
		}
		System.out.println(counter);
	}
}

チーズ (Cheese)

問題

今年も JOI 町のチーズ工場がチーズの生産を始め，ねずみが巣から顔を出した．JOI 町は東西南北に区画整理されていて，各区画は巣，チーズ工場，障害物，空き地のいずれかである．ねずみは巣から出発して全てのチーズ工場を訪れチーズを 1 個ずつ食べる．

この町には，N 個のチーズ工場があり，どの工場も１種類のチーズだけを生産している．チーズの硬さは工場によって異なっており，硬さ 1 から N までのチーズを生産するチーズ工場がちょうど 1 つずつある．

ねずみの最初の体力は 1 であり，チーズを 1 個食べるごとに体力が 1 増える．ただし，ねずみは自分の体力よりも硬いチーズを食べることはできない．

ねずみは，東西南北に隣り合う区画に 1 分で移動することができるが，障害物の区画には入ることができない．チーズ工場をチーズを食べずに通り過ぎることもできる．すべてのチーズを食べ終えるまでにかかる最短時間を求めるプログラムを書け．ただし，ねずみがチーズを食べるのにかかる時間は無視できる．

入力

入力は H+1 行ある．1 行目には 3 つの整数 H，W，N (1 ≤ H ≤ 1000，1 ≤ W ≤ 1000，1 ≤ N ≤ 9) がこの順に空白で区切られて書かれている．2 行目から H+1 行目までの各行には，'S'，'1', '2', ..., '9'，'X'，'.' からなる W 文字の文字列が書かれており，各々が各区画の状態を表している．北から i 番目，西から j 番目の区画を (i,j) と記述することにすると (1 ≤ i ≤ H, 1 ≤ j ≤ W)，第 i+1 行目の j 番目の文字は，区画 (i,j) が巣である場合は 'S' となり，障害物である場合は 'X' となり，空き地である場合は '.' となり，硬さ 1, 2, ..., 9 のチーズを生産する工場である場合はそれぞれ '1', '2', ..., '9' となる．入力には巣と硬さ 1, 2, ..., N のチーズを生産する工場がそれぞれ 1 つずつある．他のマスは障害物または空き地であることが保証されている．ねずみは全てのチーズを食べられることが保証されている．

出力

すべてのチーズを食べ終えるまでにかかる最短時間（分）を表す整数を 1 行で出力せよ．

入出力例

入力例 1

3 3 1
S..
...
..1

出力例 1

4

入力例 2

4 5 2
.X..1
....X
.XX.S
.2.X.

出力例 2

12

入力例 3

10 10 9
.X...X.S.X
6..5X..X1X
...XXXX..X
X..9X...X.
8.X2X..X3X
...XX.X4..
XX....7X..
X..X..XX..
X...X.XX..
..X.......

出力例 3

91

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


import java.util.Scanner;

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

        int a = sc.nextInt();
        int b = sc.nextInt();
        int c = sc.nextInt();
        int d = sc.nextInt();
        int e = sc.nextInt();

        int p = a > b ? c > b ? b : c : c > a ? a : c;
        int j = d > e ? e : d;

        System.out.println(p + j - 50);
    }
}

ランチ (Lunch)

問題

JOI パスタ店では，ランチのおすすめパスタと搾りたてジュースのセットメニューが好評である．このセットメニューを注文するときは，その日の 3 種類のパスタと 2 種類のジュースから 1 つずつ選ぶ．パスタとジュースの値段の合計から 50 円を引いた金額が代金となる．

ある日のパスタとジュースの値段が与えられたとき，その日のセットメニューの代金の最小値を求めるプログラムを作成せよ．

入力

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

1 行目の整数は 1 つ目のパスタの値段である．

2 行目の整数は 2 つ目のパスタの値段である．

3 行目の整数は 3 つ目のパスタの値段である．

4 行目の整数は 1 つ目のジュースの値段である．

5 行目の整数は 2 つ目のジュースの値段である．

ただし，与えられる入力データにおいては全てのパスタとジュースの値段は 100 円以上 2000 円以下であることが保証されている．

出力

その日のセットメニューの代金の最小値を 1 行で出力せよ．

入出力例

入力例 1

800
700
900
198
330

出力例 1

848

入出力例 1 では，2 つ目のパスタと 1 つ目のジュースを組み合わせた場合の
700 + 198 - 50 = 848 がその日のセットメニューの代金の最小値である．

入力例 2

1999
1999
100
189
100

出力例 2

150

入出力例 2 では，3 つ目のパスタと 2 つ目のジュースを組み合わせた場合の
100 + 100 - 50 = 150 がその日のセットメニューの代金の最小値である．

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


import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int a = in.nextInt();
		int b = in.nextInt();
		int c = in.nextInt();
		int tcal = c;
		int cnt = 0;
		int d[] = new int[100];
		for(int i = 0; i < n; i++){
			d[i] = in.nextInt();
			int tcaljn = tcal / a + b * cnt;
			int tcaln = tcal + d[i] / (a + b * (cnt + 1));
			if((c / a * 200 ) > d[i] * 100 / b){
				continue;
			}else if(tcaljn > tcaln){
				break;
			}
			tcal += d[i];
			cnt++;
		}
		System.out.println(tcal / (a + (cnt * b)));
	}
}

最高のピザ (Best Pizza)

問題

K 理事長は，JOI 市の中心部にある JOI ピザ店の常連客である．彼はある事情により，今月から節約生活を始めることにした．そこで彼は，JOI ピザ店で注文できるピザのうち，1 ドルあたりのカロリーが最大となるようなピザを注文したいと思った．このようなピザを「最高のピザ」と呼ぶことにしよう．「最高のピザ」は 1 種類とは限らない．

JOI ピザでは N 種類のトッピングから何種類かを自由に選び，基本の生地の上に載せたものを注文することができる．同種のトッピングを 2 つ以上載せることはできない．生地にトッピングを 1 種類も載せないピザも注文できる．生地の値段は A ドルであり，トッピングの値段はいずれも B ドルである．ピザの値段は，生地の値段と載せたトッピングの値段の合計である．すなわち，トッピングを k 種類 (0 ≦ k ≦ N) 載せたピザの値段は A + k × B ドルである．ピザ全体のカロリーは，生地のカロリーと載せたトッピングのカロリーの合計である．

生地の値段とトッピングの値段，および，生地と各トッピングのカロリーの値が与えられたとき，「最高のピザ」の 1 ドルあたりのカロリー数を求めるプログラムを作成せよ．

入力

入力は N + 3 行からなる．

1 行目にはトッピングの種類数を表す 1 つの整数 N (1 ≦ N ≦ 100) が書かれている．2 行目には 2 つの整数 A, B (1 ≦ A ≦ 1000，1 ≦ B ≦ 1000) が空白を区切りとして書かれている．A は生地の値段，B はトッピングの値段を表す．3 行目には，生地のカロリー数を表す 1 つの整数 C (1 ≦ C ≦ 10000) が書かれている．

3 + i 行目 (1 ≦ i ≦ N) には，i 番目のトッピングのカロリー数を表す 1 つの整数 Di (1 ≦ Di ≦ 10000) が書かれている．

出力

「最高のピザ」の 1 ドルあたりのカロリー数を 1 行で出力せよ．ただし，小数点以下は切り捨てて整数値で出力せよ．

入出力例

入力例 1

3
12 2
200
50
300
100

出力例 1

37

入出力例 1 では，2 番目と 3 番目のトッピングを載せると，200 + 300 + 100 = 600 カロリーで 12 + 2 × 2 = 16 ドルのピザになる．

このピザは 1 ドルあたり 600 / 16 = 37.5 カロリーになる．これが「最高のピザ」となるので，37.5 の小数点以下を切り捨てた 37 を出力する．

入力例 2

4
20 3
900
300
100
400
1300

出力例 2

100

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


import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Scanner sc = new Scanner(System.in);
		int W = sc.nextInt();//南北方向にまっすぐに伸びる 道路
		int H = sc.nextInt();//東西方向にまっすぐに伸びる 道路
		int N = sc.nextInt();//観光スポットの数
		int i;
		int j = 0;
		int x[] = new int[N];
		int y[] = new int[N];
		int c = 0;

		for(i = 0; i < N; i++){
			x[i] = sc.nextInt();
			y[i] = sc.nextInt();
		}

		while(true){//斜め移動上
			if(x[N-2] == x[N-1] && y[N-2] == y[N-1])break;
			if(x[j] < x[j+1] && y[j] < y[j+1]){
				x[j]++;
				y[j]++;
				c++;
			}

			else if(x[j] > x[j+1] && y[j] > y[j+1]){//斜め移動下
				x[j]--;
				y[j]--;
				c++;
			}

			else if(x[j] < x[j+1] && y[j] == y[j+1]){//目的地よりも現在地が左側でy軸は等しい
				x[j]++;
				c++;
			}

			else if(x[j] == x[j+1] && y[j] < y[j+1]){//目的地よりも現在地が下側でx軸は等しい
				y[j]++;
				c++;
			}

			else if(x[j] > x[j+1] && y[j] == y[j+1]){//目的地よりも現在地が右側でy軸は等しい
				x[j]--;
				c++;
			}

			else if(x[j] == x[j+1] && y[j] > y[j+1]){//目的地よりも現在地が上側でx軸は等しい
				y[j]--;
				c++;
			}

			else if(x[j] > x[j+1] && y[j] < y[j+1]){
				x[j]--;
				y[j]++;
				c+=2;
			}

			else if(x[j] < x[j+1] && y[j] > y[j+1]){
				x[j]++;
				y[j]--;
				c+=2;
			}

			if(x[j] == x[j+1] && y[j] == y[j+1]){
				j++;
			}

		}

		System.out.println(c);

	}

}

問題 3: 超都観光 (Super Metropolis)

問題

JOI 君は，IOI 国にある超都という都市の観光ツアーを計画することになった．

超都は，南北方向にまっすぐに伸びる W 本の道路と，東西方向にまっすぐに伸びる H 本の道路により，碁盤の目の形に区分けされている．

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

さらに，下図のように，各交差点からは１つ北東の交差点への道がある（最も北の道路上の交差点と最も東の道路上の交差点を除く）．
また，１つ南西の交差点への道もある（最も南の道路上の交差点と最も西の道路上の交差点を除く）．
すなわち，交差点 (i, j) からは，もし交差点 (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1) があるときは，それらの交差点へ１本の道を使って行くことが出来る．それに加え，もし交差点 (i - 1, j - 1), (i + 1, j + 1) があるときは，それらの交差点へも１本の道を使って行くことが出来る．

JOI 君はツアーの計画として既に N 個の観光スポットをどのような順番で訪れるかを決めている．
i 番目 (1 ≦ i ≦ N) に訪れる観光スポットは交差点 (Xi, Yi) にある．
JOI 君は，ツアーにかかる時間をできるだけ短くするために，通らなければならない道の本数を少なくしたい．
観光スポットを事前に決めた順番で訪れるために通らなければならない道の本数の合計の最小値を求めるプログラムを作成せよ．

ただし，ツアーの開始地点は交差点 (X1, Y1) である．また，ツアーの途中で超都の外へ移動してはならないものとする．
また，JOI 君は，観光スポットのある交差点を，観光スポットを訪れずに通過することもできる．

「道の本数の合計」についての補足．ツアーの途中で同じ道を２回以上通ることもできる．その場合，「道の本数の合計」としては，その道については通った回数だけ重複して数えるものとする．

入力

入力は 1 + N 行からなる．

1 行目には，空白を区切りとして 3 つの整数 W, H, N (2 ≤ W ≤ 10000, 2 ≤ H ≤ 10000, 1 ≤ N ≤ 1000) が書かれている．

続く N 行のうちの i 行目 (1 ≤ i ≤ N) には，2 つの整数 Xi, Yi (1 ≤ Xi ≤ W, 1 ≤ Yi ≤ H) が空白を区切りとして書かれている．これは，i 番目に訪れる観光スポットのある交差点が (Xi, Yi) であることを表す．

出力

観光スポットを順番に訪れるために通る道の本数の合計の最小値を 1 行で出力せよ．

入出力例

入力例 1

4 3 3
1 1
3 3
4 1

出力例 1

5

入出力例 1 では，例えば (1, 1), (2, 2), (3, 3), (3, 2), (4, 2), (4, 1) の順で交差点を訪れれば良い．

入力例 2

4 3 5
1 3
4 3
2 2
2 2
1 3

出力例 2

7

入出力例 2 のように，同じ交差点に複数回訪れることもある．

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


import java.util.*;

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

        int dayRcoin = scan.nextInt();
        int weekRcoin = scan.nextInt();
        int aimRcoin = scan.nextInt();
        int nowRcoin = 0;
        int logindays;

        for(logindays=0; nowRcoin<aimRcoin; logindays++)
            nowRcoin+=logindays%7==6 ? dayRcoin+weekRcoin : dayRcoin;

        System.out.println(logindays);
    }
}

ソーシャルゲーム (Social Game)

問題文

JOI 君は明日から新たにソーシャルゲームを始めることにした．

このソーシャルゲームでは，1 日につき 1 回までログインすることができ，ログインするたびに A 枚のコインが得られる．

また，月曜日から日曜日まで 7 日連続でログインすると，そのたびに，追加で B 枚のコインが得られる．

これ以外にコインがもらえることはない．

明日は月曜日である．JOI 君が少なくとも C 枚のコインを得るためにログインしなければならない回数の最小値を求めよ．

制約

1 ≦ A ≦ 1000

0 ≦ B ≦ 1000

1 ≦ C ≦ 1000000 (= 10^6)

入力・出力

入力

入力は以下の形式で標準入力から与えられる．

A B C

出力

JOI 君が少なくとも C 枚のコインを得るためにログインしなければならない回数の最小値を出力せよ．

入出力例

入力例 1

3 0 10

出力例 1

4

1 回のログインあたり 3 枚のコインが得られ，10 枚のコインを集めたい．

JOI 君は，月曜日から連続 4 日間ログインすることで 12 枚のコインが得られる．

3 回以下のログインで 10 枚以上のコインを得ることはできないので，JOI 君がログインしなければならない回数の最小値は 4 である．従って，4 を出力する．

入力例 2

1 2 10

出力例 2

8

1 回のログインあたり 1 枚のコインが得られる．それとは別に，1 週間連続でログインすることで 2 枚のコインが得られる．10 枚のコインを集めたい．

月曜日から日曜日まで連続でログインすると，日々のコイン 7 枚に加えて，2 枚のコインが得られるため，合計 9 枚のコインが得られる．従って，更にもう 1 回ログインすることにより，10 枚のコインが得られる．

7 回以下のログインで 10 枚以上のコインを得ることはできないので，JOI 君がログインしなければならない回数の最小値は 8 である．従って，8 を出力する．

情報オリンピック日本委員会作 『第 18 回日本情報オリンピック JOI 2018/2019 予選競技課題』


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

public class Main {

	static int tc;
	public static void main(String[] args) {
		for (tc = 1; read(); tc++) {
			solve();
		}
	}

	static int N;
	static Scanner sc = new Scanner(System.in);
	static boolean read() {
		N = sc.nextInt();
		if (N == 0) return false;
		return true;
	}

	static void solve() {
		int val = 1;
		int[][] jpeg = new int[100][100];
		jpeg[0][0] = val++;
		int m = 0, x = 1, y = 0;
		for (int i = 1; i < N * 2; i++) {
			if (i < N - 1) {
				if (i % 2 == 0) {
					for (; y >= 0; x++, y--) {
						jpeg[y][x] = val++;
					}
				} else {
					for (; x >= 0; x--, y++) {
						jpeg[y][x] = val++;
					}
				}
			} else {
				if (i % 2 == 0) {
					for (; x < N; x++, y--) {
						jpeg[y][x] = val++;
					}
				} else {
					for (; y < N; x--, y++) {
						jpeg[y][x] = val++;
					}
				}
			}

			if (i < N - 1) {
				if (i % 2 == 0) {
					y++;
				} else {
					x++;
				}
			} else {
				if (i % 2 == 0) {
					x--; y += 2;
				} else {
					x += 2; y--;
				}
			}
		}

		System.out.println("Case " + tc + ":");
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (j != N - 1) {
					System.out.print(jpeg[i][j] + " ");
				} else {
					System.out.println(jpeg[i][j]);
				}
			}
		}
	}
}

JPEG Compression

The fundamental idea in the JPEG compression algorithm is to sort coeffi-
cient of given image by zigzag path and encode it. In this problem, we don’t
discuss about details of the algorithm, but you are asked to make simple pro-
gram. You are given single integer N , and you must output zigzag path on
a matrix where size is N by N . The zigzag scanning is start at the upper-left
corner (0, 0) and end up at the bottom-right corner. See the following Figure
and sample output to make sure rule of the zigzag scanning. For example, if you
are given N = 8, corresponding output should be a matrix shown in right-side
of the Figure. This matrix consists of visited time for each element.

Input

Several test cases are given. Each test case consists of one integer N (0 < N <
10) in a line. The input will end at a line contains single zero.

Output

For each input, you must output a matrix where each element is the visited
time. All numbers in the matrix must be right justified in a field of width 3.
Each matrix should be prefixed by a header “Case x:” where x equals test case
number.

Sample Input

3
4
0

Output for the Sample Input

Case 1:
1 2 6
3 5 7
4 8 9
Case 2:
1 2 6 7
3 5 8 13
4 9 12 14
10 11 15 16


import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Main
{
	public static void main(String[] args)
	{
		Scanner in=new Scanner(System.in);
		for(;;)
		{
			int n=in.nextInt();
			if(n==0)
				return;
			Map<String,Integer>HM=new HashMap<String, Integer>();
			String ans="";
			boolean judge=false;
			int index=n;
			for(int i=0;i<n;i++)
			{
				String str=in.next();
				int cnt=1;
				if(HM.containsKey(str))
					cnt+=HM.get(str);
				HM.put(str,cnt);
				if(cnt>n/2)
				{
					judge=true;
					ans=str;
					index=i+1;
					break;
				}
			}
			for(int i=0;i<n-index;i++)
			{
				int hoge=in.nextInt();
			}
			System.out.println(judge ? ans:"NO COLOR");
		}
	}
	static public void debug(Object... o)
	{
		System.out.println(Arrays.deepToString(o));
	}
}

What Color Is The Universe?

On a clear night, a boy, Campanella looked up at the sky, there were many stars which have different colors such as red, yellow, green, blue, purple, etc. He was watching the stars and just lost track of time. Presently, he wondered,

"There are many stars in the space. What color is the universe if I look up it from outside?"

Until he found the answer to this question, he couldn't sleep. After a moment's thought, he proposed a hypothesis,

"When I observe the stars in the sky, if more than half of the stars have the same color, that is the color of the universe."

He has collected data of stars in the universe after consistently observing them. However, when he try to count the number of star, he was in bed sick with a cold. You decided to help him by developing a program to identify the color of the universe.

You are given an array A. Let |A| be the number of element in A, and let Nm be the number of m in A. For example, if A = {3, 1, 2, 3, 3, 1, 5, 3}, |A| = 8, N3 = 4, N1 = 2, N5 = 1. Your program have to find m such that:

Nm > (|A| / 2 )

If there is no such m, you also have to report the fact. There is no
such m for the above example, but for a array A = {5, 2, 5, 3, 4, 5, 5}, 5 is the answer.

Input

There are several test cases. For each test case, in the first line |A| is given. In the next line, there will be |A| integers. The integers are less than 231 and |A| < 1,000,000. The input terminate with a line which contains single 0.

Output

For each test case, output m in a line. If there is no answer, output "NO COLOR" in a line.

Sample Input

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

Output for the Sample Input

NO COLOR
5


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

class Main {
    public static void main(String[] args) {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String line = br.readLine();
            StringTokenizer st = new StringTokenizer(line, " ");
            while(st.hasMoreTokens()) {
            	int x = Integer.parseInt(st.nextToken());
                int y = Integer.parseInt(st.nextToken());

            	if(x < y) {
            		x = x + y;
                	y = x - y;
                	x = x - y;

            	}

            	while(y > 0) {
            		int r = x % y;
            		x = y;
            		y = r;
            	}
            	System.out.println(x);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Problem A: Greatest Common Divisor

Please find the greatest common divisor of two natural numbers. A clue is: The Euclid's algorithm is a way to resolve this task.

Input

The input file consists of several lines with pairs of two natural numbers in each line. The numbers do not exceed 100000.

The number of pairs (datasets) is less than 50.

Output

Your program has to print the greatest common divisor for each pair of input numbers. Print each result on a new line.

Sample Input

57 38
60 84

Output for the Sample Input

19
12


import java.util.*;
public class Main
{
	static int n,ans;
	static int a[];
	public static void main(String[] args)
	{
		Scanner in=new Scanner(System.in);
		for(;;)
		{
			n=in.nextInt(); //n<=20
			if(n==0)
				return;
			a=new int[n];
			for(int i=0;i<n;i++)
				a[i]=in.nextInt();
			ans=1000000;
			dfs(0,0,0);
			System.out.println(ans);
		}
	}

	static void dfs(int i,int A,int B)
	{
		if(i==n)
			ans=Math.min(ans,Math.abs(A-B));
		else
		{
			dfs(i+1,A+a[i],B);
			dfs(i+1,A,B+a[i]);
		}
	}
}

Problem 05: Split Up!

勇者ポン太とその親友同じく勇者ゴン太は、これから壮大な冒険へと出発するために、それぞれ仲間を求めてルイーダの酒場へやって来ました。酒場には、冒険に出たくてうずうずしている武闘家や僧侶、魔法使いがたくさん居ます。

心やさしいゴン太はポン太を気遣い、「先に仲間を選んでいいよ。」と言いました。

一方、ポン太もゴン太が心配でなりません。「いや、君が先に選んでいいよ。」と言い返しました。

お互い譲り合いが続き、ついにルイーダがこう提案しました。「じゃあ、ここにいる n 人の登録者をそれぞれのパーティの合計戦闘力がなるべく均等になるように、この"パーティ分けマシン"で分けてあげるわ。」

あなたに与えられた仕事は、パーティ分けマシンに組み込まれているプログラムを作成することです。

このプログラムは　n 個の整数を入力し、それらを２つのグループ A, B に分けたときの、A に含まれる整数の合計値と B に含まれる整数の合計値の差の最小値を出力しなければなりません。

このマシンのおかげで、ポン太とゴン太は仲良く仲間を見つけ、壮大な冒険へと出かけて行きました・・。

Input

入力として複数のデータセットが与えられます。各データセットは以下の形式で与えられます：

n (登録者の数： 整数)

a1 a2 ... an　（各登録者の戦闘力： 空白区切りの整数）

n は 20 以下であり、各登録者の戦闘力は 100 万を越えません。

n が 0 のとき入力の終わりとします。

Output

各データセットに対して、最小値を1行に出力して下さい。

Sample Input

5
1 2 3 4 5
4
2 3 5 7
0

Output for the Sample Input

1
1


import java.util.Scanner;

public class Main {
	static int n, m, w, h, S;
	static double l[], r[];
	static double x[], y[];
	static double s[];
	static int a[];

	public static int check(int aid, int low, int high) {
		if (high - low == 1) {
			return low;
		}

		int mid = (low + high) / 2;
		double v1x = -w;
		double v1y = l[mid] - r[mid];
		double v2x = x[aid] - w;
		double v2y = y[aid] - r[mid];
		double cross = v1x * v2y - v1y * v2x;

		if (0 < cross) {
			return check(aid, low, mid);
		} else {
			return check(aid, mid, high);
		}
	}

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

		while (true) {
			n = sc.nextInt();
			m = sc.nextInt();
			w = sc.nextInt();
			h = sc.nextInt();
			S = sc.nextInt();
			if ((n | m | w | h | S) == 0) {
				break;
			}
			l = new double[m + 1];
			r = new double[m + 1];
			x = new double[n];
			y = new double[n];
			a = new int[m];
			s = new double[m];
			l[0] = r[0] = 0;
			for (int i = 0; i < m ;i++) {
				l[i + 1] = sc.nextDouble();
				r[i + 1] = sc.nextDouble();
			}
			for (int i = 0; i < n ;i++) {
				x[i] = sc.nextDouble();
				y[i] = sc.nextDouble();
			}
			for (int i = 0; i < n; i++) {
				a[check(i, 0, m + 1)]++;
			}
			for (int i = 0; i < m; i++) {
				s[i] = (l[i + 1] - l[i] + r[i + 1] - r[i]) * w / 2;
			}
			int low = 0;
			int high = 0;
			int max = 0;
			int ns = 0;
			int na = 0;
			while (low < m && high < m) {
				ns = 0;
				na = 0;
				for (int i = low; i <= high; i++) {
					ns += s[i];
					na += a[i];
				}
				if (ns <= w * h - S) {
					high++;
					max = Math.max(max, na);
				} else {
					low++;
				}
			}
			System.out.println(n - max);
		}
	}
}

Problem F: Cutting a Chocolate

Turtle Shi-ta and turtle Be-ko decided to divide a chocolate.
The shape of the chocolate is rectangle. The corners of the chocolate are put on (0,0), (w,0), (w,h) and (0,h).
The chocolate has lines for cutting.
They cut the chocolate only along some of these lines.

The lines are expressed as follows.
There are m points on the line connected between (0,0) and (0,h), and between (w,0) and (w,h).
Each i-th point, ordered by y value (i = 0 then y =0), is connected as cutting line.
These lines do not share any point where 0 < x < w .
They can share points where x = 0 or x = w .
However, (0, li ) = (0,lj ) and (w,ri ) = (w,rj ) implies i = j .
The following figure shows the example of the chocolate.

There are n special almonds, so delicious but high in calories on the chocolate.
Almonds are circle but their radius is too small. You can ignore radius of almonds.
The position of almond is expressed as (x,y) coordinate.

Two turtles are so selfish. Both of them have requirement for cutting.

Shi-ta's requirement is that the piece for her is continuous.
It is possible for her that she cannot get any chocolate.
Assume that the minimum index of the piece is i and the maximum is k .
She must have all pieces between i and k .
For example, chocolate piece 1,2,3 is continuous but 1,3 or 0,2,4 is not continuous.

Be-ko requires that the area of her chocolate is at least S .
She is worry about her weight. So she wants the number of almond on her chocolate is as few as possible.

They doesn't want to make remainder of the chocolate because the chocolate is expensive.

Your task is to compute the minumum number of Beko's almonds if both of their requirment are satisfied.

Input

Input consists of multiple test cases.

Each dataset is given in the following format.

n m w h S
l0 r0
...
lm-1 rm-1
x0 y0
...
xn-1 yn-1

The last line contains five 0s.
n is the number of almonds.
m is the number of lines.
w is the width of the chocolate.
h is the height of the chocolate.
S is the area that Be-ko wants to eat.
Input is integer except xi yi.

Input satisfies following constraints.

1 ≤ n ≤ 30000

1 ≤ m ≤ 30000

1 ≤ w ≤ 200

1 ≤ h ≤ 1000000

0 ≤ S ≤ w*h

If i < j then li ≤ lj and ri ≤ rj and then i -th lines and j -th lines share at most 1 point.
It is assured that lm-1 and rm-1 are h.
xi yi is floating point number with ten digits.
It is assured that they are inside of the chocolate.
It is assured that the distance between points and any lines is at least 0.00001.

Output

You should output the minumum number of almonds for Be-ko.

Sample input

2 3 10 10 50
3 3
6 6
10 10
4.0000000000 4.0000000000
7.0000000000 7.0000000000
2 3 10 10 70
3 3
6 6
10 10
4.0000000000 4.0000000000
7.0000000000 7.0000000000
2 3 10 10 30
3 3
6 6
10 10
4.0000000000 4.0000000000
7.0000000000 7.0000000000
2 3 10 10 40
3 3
6 6
10 10
4.0000000000 4.0000000000
7.0000000000 7.0000000000
2 3 10 10 100
3 3
6 6
10 10
4.0000000000 4.0000000000
7.0000000000 7.0000000000
0 0 0 0 0

Sample output

1
1
0
1
2


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

public class Main {
	public static void main(String args[]){
		Scanner in = new Scanner(System.in);
		int cnt=1;
			while(in.hasNextInt()){
				int n = in.nextInt();
				if(n==0) break;
				int xs[] = new int[n], ys[] = new int[n];
				for(int i=0; i<n; i++){
					xs[i] = in.nextInt();
					ys[i] = in.nextInt();
				}
				int ans = 0;
				for(int i=0; i<n; i++){
					ans += get2Area(xs[i], ys[i], xs[(i+1)%n], ys[(i+1)%n]);
				}
				System.out.printf("%d %.1f\n", cnt, Math.abs(ans/2.0));
				cnt++;
			}
	}

	private static int get2Area(int x1, int y1, int x2, int y2){
		return x2*y1 - x1*y2;
	}
}

Area of Polygons

Polygons are the most fundamental objects in geometric processing.
Complex figures are often represented and handled as polygons
with many short sides.
If you are interested in the processing of geometric data,
you'd better try some programming exercises about basic
operations on polygons.

Your job in this problem is to write a program that computes the area of polygons.

A polygon is represented by a sequence of points that are its vertices.
If the vertices p1, p2, ..., pn are given, line segments connecting
pi and pi+1 (1 <= i <= n-1) are sides of the polygon.
The line segment connecting pn and p1 is also a side of the polygon.

You can assume that the polygon is not degenerate.
Namely, the following facts can be assumed without any input data checking.

No point will occur as a vertex more than once.

Two sides can intersect only at a common endpoint (vertex).

The polygon has at least 3 vertices.

Note that the polygon is not necessarily convex.
In other words, an inner angle may be larger than 180 degrees.

Input

The input contains multiple data sets, each representing a polygon.
A data set is given in the following format.

n
x1 y1
x2 y2
...
xn yn

The first integer n is the number of vertices,
such that 3 <= n <= 50.
The coordinate of a vertex pi is given by (xi, yi).
xi and yi are integers between 0 and 1000 inclusive.
The coordinates of vertices are given in the order
of clockwise visit of them.

The end of input is indicated by a data set with 0 as the value of n.

Output

For each data set, your program should output its sequence number
(1 for the first data set, 2 for the second, etc.) and the area of the polygon separated by a single space. The area should be printed with one digit to the right of the decimal point.

The sequence number and the area should be printed on the same line.
Since your result is checked by an automatic grading program,
you should not insert any extra characters nor lines on the output.

Sample Input

3
1 1
3 4
6 0

7
0 0
10 10
0 20
10 30
0 40
100 40
100 0

0

Output for the Sample Input

1 8.5
2 3800.0


import java.util.Scanner;

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

		while (true)
		{
			int m = sc.nextInt();
			int n = sc.nextInt();
			if (n == 0 && m == 0)
				break;
			int x = 1;
			int y = 1;
			int dx[] = { 0, 1, 0,-1};
			int dy[] = { 1, 0,-1, 0};
			int d = 0;
			while (true)
			{
				String str = sc.next();
				if (str.equals("STOP"))
				{
					System.out.printf("%d %d\n", x, y);
					break;
				}
				else if (str.equals("FORWARD"))
				{
					int k = sc.nextInt();
					for (int i = 0; i < k; i++)
					{
						if (x + dx[d] < 1 || m < x + dx[d])
							break;
						x += dx[d];
					}
					for (int i = 0; i < k; i++)
					{
						if (y + dy[d] < 1 || n < y + dy[d])
							break;
						y += dy[d];
					}
				}
				else if (str.equals("BACKWARD"))
				{
					int k = sc.nextInt();
					for (int i = 0; i < k; i++)
					{
						if (x - dx[d] < 1 || m < x - dx[d])
							break;
						x -= dx[d];
					}
					for (int i = 0; i < k; i++)
					{
						if (y - dy[d] < 1 || n < y - dy[d])
							break;
						y -= dy[d];
					}
				}
				else if (str.equals("RIGHT"))
				{
					d++;
					if (d == 4) d = 0;
				}
				else if (str.equals("LEFT"))
				{
					d--;
					if (d == -1) d = 3;
				}
			}
		}
	}
}

Where's Your Robot?

You have full control over a robot that walks around in a rectangular
field paved with square tiles like a chessboard. There are m
columns of tiles from west to east, and n rows of tiles from
south to north (1 <= m, n <= 100). Each tile is given a pair
of coordinates, such as (i, j), where 1 <= i <= m
and 1 <= j <= n.

Your robot is initially on the center of the tile at (1, 1), that is,
one at the southwest corner of the field, facing straight north. It
can move either forward or backward, or can change its facing
direction by ninety degrees at a time, according to a command you give
to it, which is one of the following.

FORWARD k

Go forward by k tiles to its facing direction (1 <= k < 100).

BACKWARD k

Go backward by k tiles, without changing its facing direction
(1 <= k < 100).

RIGHT

Turn to the right by ninety degrees.

LEFT

Turn to the left by ninety degrees.

STOP

Stop.

While executing either a "FORWARD" or a
"BACKWARD" command, the robot may bump against the
wall surrounding the field. If that happens, the robot gives up the
command execution there and stands at the center of the tile right in
front of the wall, without changing its direction.

After finishing or giving up execution of a given command, your robot
will stand by for your next command.

Input

The input consists of one or more command sequences. Each input line
has at most fifty characters.

The first line of a command sequence contains two integer numbers
telling the size of the field, the first number being the number of
columns and the second being the number of rows. There might be white
spaces (blanks and/or tabs) before, in between, or after the two numbers.
Two zeros as field size indicates the end of input.

Each of the following lines of a command sequence contains a command
to the robot. When a command has an argument, one or more white
spaces are put between them. White spaces may also appear before and
after the command and/or its argument.

A command sequence is terminated by a line containing a
"STOP" command. The next command sequence, if any,
starts from the next line.

Output

The output should be one line for each command sequence in the input.
It should contain two numbers i and j of the coordinate pair
(i, j), in this order, of the tile on which your robot stops.
Two numbers should be separated by one white spaces.

Sample Input

6 5
FORWARD 3
RIGHT
FORWARD 5
LEFT
BACKWARD 2
STOP
3 1
FORWARD 2
STOP
0 0

Output for the Sample Input

6 2
1 1


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

public class Main {
	public static void main(String[] args) {
		Main p = new Main();
	}

	public Main() {
		Scanner sc = new Scanner(System.in);
		while(true){
			int n = sc.nextInt();
			if(n==0)
				break;

			int m = sc.nextInt();

			int[][] xy = new int[2][m];

			int[][] xx = new int[8][m];
			int[][] yy = new int[8][m];
			xy[0][0] = sc.nextInt();
			xy[1][0] = sc.nextInt();
			for(int i=1;i<m;i++){
				xy[0][i] = sc.nextInt() - xy[0][0];
				xy[1][i] = sc.nextInt() - xy[1][0];
			}
			xy[0][0] = xy[1][0] = 0;

			for(int i=0;i<4;i++){
				for(int j=0;j<m;j++){
					xx[i][j] = xy[i%2][j] * (i==0 || i==3 ? 1 : -1);
					yy[i][j] = xy[(i+1)%2][j] * (i/2==0 ? 1 : -1);
				}

				for(int j=m-1;j>=0;j--){
					xx[i+4][m-j-1] = xx[i][j]-xx[i][m-1];
					yy[i+4][m-j-1] = yy[i][j]-yy[i][m-1];
				}
//				System.out.println(Arrays.toString(xx[i]));
//				System.out.println(Arrays.toString(xx[i+4]));
			}

			for(int i=0;i<n;i++){
				m = sc.nextInt();
				xy = new int[2][m];
				xy[0][0] = sc.nextInt();
				xy[1][0] = sc.nextInt();
				for(int j=1;j<m;j++){
					xy[0][j] = sc.nextInt() - xy[0][0];
					xy[1][j] = sc.nextInt() - xy[1][0];
				}
				xy[0][0] = xy[1][0] = 0;
				if(solve(xy, xx, yy))
					System.out.println(i+1);
			}
			System.out.println("+++++");
		}
	}

	public boolean solve(int[][] xy, int[][] xx, int[][] yy) {
		if(xy[0].length != xx[0].length)
			return false;

		boolean res = false;
		for(int i=0;i<xx.length;i++){
			boolean r = true;
			for(int j=0;j<xx[i].length;j++){
				if(xx[i][j]!=xy[0][j] || yy[i][j]!=xy[1][j]){
					r=false;
					break;
				}
			}
			res |= r;
		}

		return res;
	}

}

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.*;
import java.lang.*;
import java.math.*;

public class Main {
	Scanner sc = new Scanner(System.in);
	class point{
		public int x;
		public int y;
		point(int x,int y){
			this.x = x;
			this.y = y;
		}
		point rot(int seed){
			if(seed == 0){
				return new point(this.x,this.y);
			}else if(seed == 1){
				return new point(-this.x,-this.y);
			}else if(seed == 2){
				return new point(this.y,-this.x);
			}else{// if(seed == 3){
				return new point(-this.y,this.x);
			}
		}
		point org(point target){
			point ret = new point(this.x - target.x,this.y - target.y);
			return ret;
		}
		public boolean equ(point target){
			return this.x == target.x && this.y == target.y ;
		}
	}
	class polyline{
		public int m = 0;
		public point[] p;
		polyline(){}
		polyline(int m,Scanner sc){
			this.m  =m;
			p = new point[m];
			point org = new point(sc.nextInt(),sc.nextInt());
			p[0] = org.org(org);
			for(int i = 1; i < m; i++){
				p[i] = new point(sc.nextInt(),sc.nextInt());
				p[i] = p[i].org(org);
			}
		}
		polyline[] generate8(){
			polyline ret[] = new polyline[8];
			for(int i =0 ; i < 4; i ++){
				point[] a = new point[m];
				point org = p[0];
				for(int j = 0; j < m;j++){
					a[j] = p[j].org(org).rot(i);
				}
				ret[i] = new polyline();
				ret[i].m = m;
				ret[i].p = a;
			}
			for(int i =0 ; i < 4; i ++){
				point[] a = new point[m];
				point org = p[m-1];
				for(int j = 0; j < m;j++){
					a[j] = p[m-j-1].org(org).rot(i);
				}
				ret[i+4] = new polyline();
				ret[i+4].m = m;
				ret[i+4].p = a;
			}
			return ret;
		}
		boolean equ(polyline target){
			if(this.m != target.m){
				return false;
			}
			for(int i =0;i < m;i++){
				if(!this.p[i].equ(target.p[i])){
					return false;
				}
			}
			return true;
		}
		void print(){
			System.out.println(this.m);
			for(int i = 0;i < m; i++){
				System.out.println(this.p[i].x + " " + this.p[i].y);
			}
			System.out.println();
		}
	}
	void run(){
		for(;;){
			int n = sc.nextInt();
			if(n == 0) break;
			polyline base1 =new polyline(sc.nextInt(),sc);
			polyline[] base = base1.generate8();
			/*
			for(int i = 0; i < 8 ; i++){
				System.out.println("base "+i);
				base[i].print();
			}
			*/
			for(int i = 0; i < n; i++){
				polyline lines = new polyline(sc.nextInt(),sc);
			/*
				System.out.println("lines "+(i+1));
				lines.print();
				System.out.println("------ ");
			*/
				for(int j = 0; j < 8; j++){
					if(lines.equ(base[j])){
						System.out.println(i+1);
						continue;
					}
				}
			}
			System.out.println("+++++");
		}
	}
	public static void main(String[] args){
		Main m = new Main();
		m.run();
	}
}


import java.util.*;

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

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.util.Scanner;

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


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

public class Main {
    public static void main(String[] args) {
        FastScanner sc = new FastScanner();
        List<Long> seven = new ArrayList<>();
        for (long i = 6; i <= 300000; i += 7) {
            seven.add(i);
            if (i + 2 > 300000) {
                break;
            }
            seven.add(i + 2);
        }
        boolean[] sevenPrime = new boolean[300001];
        for (long num : seven) {
            if (!isPrime(num)) {
                continue;
            }
            sevenPrime[(int) num] = true;
        }
        while (true) {
            long n = sc.nextLong();
            if (n == 1) {
                return;
            }
            List<Integer> ans = new ArrayList<>();
            for (int i = 2; i <= n; i++) {
                if (!sevenPrime[i]) {
                    continue;
                }
                if (n % i == 0) {
                    ans.add(i);
                }
            }
            System.out.print(n + ":");
            for (long a : ans) {
                System.out.printf(" %d", a);
            }
            System.out.println();
        }
    }

    public static boolean isSeven(long x) {
        if (x % 7 == 1 || x % 7 == 6) {
            return true;
        }
        return false;
    }

    public static boolean isPrime(long x) {
        if (x == 1) {
            return false;
        }
        for (long i = 2; i * i <= x; i++) {
            if (x % i == 0 && isSeven(i)) {
                return false;
            }
        }
        return true;
    }
}

class FastScanner {
    private final InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;

    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        } else {
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }

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

    private static boolean isPrintableChar(int c) {
        return 33 <= c && c <= 126;
    }

    public boolean hasNext() {
        while (hasNextByte() && !isPrintableChar(buffer[ptr]))
            ptr++;
        return hasNextByte();
    }

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

    public long nextLong() {
        if (!hasNext())
            throw new NoSuchElementException();
        long n = 0;
        boolean minus = false;
        int b = readByte();
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        if (b < '0' || '9' < b) {
            throw new NumberFormatException();
        }
        while (true) {
            if ('0' <= b && b <= '9') {
                n *= 10;
                n += b - '0';
            } else if (b == -1 || !isPrintableChar(b)) {
                return minus ? -n : n;
            } else {
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }

    public int nextInt() {
        long nl = nextLong();
        if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE)
            throw new NumberFormatException();
        return (int) nl;
    }

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

Problem B: Monday-Saturday Prime Factors

Chief Judge's log, stardate 48642.5.
We have decided to make a problem from elementary number theory.
The problem looks like finding all prime factors of a positive integer,
but it is not.

A positive integer whose remainder divided by 7 is either 1 or 6 is called
a 7N+{1,6} number.
But as it is hard to pronounce,
we shall call it a Monday-Saturday number.

For Monday-Saturday numbers a and b,
we say a is a Monday-Saturday divisor of b
if there exists a Monday-Saturday number x
such that ax = b.
It is easy to show that
for any Monday-Saturday numbers a and b,
it holds that a is
a Monday-Saturday divisor of b
if and only if
a is a divisor of b in the usual sense.

We call a Monday-Saturday number a Monday-Saturday prime
if it is greater than 1 and has no Monday-Saturday divisors
other than itself and 1.
A Monday-Saturday number which is a prime in the usual sense
is a Monday-Saturday prime
but the converse does not always hold.
For example, 27 is a Monday-Saturday prime
although it is not a prime in the usual sense.
We call a Monday-Saturday prime
which is a Monday-Saturday divisor of a Monday-Saturday number a
a Monday-Saturday prime factor of a.
For example, 27 is one of the Monday-Saturday prime factors of 216,
since 27 is a Monday-Saturday prime
and 216 = 27 × 8 holds.

Any Monday-Saturday number greater than 1
can be expressed as a product of one or more Monday-Saturday primes.
The expression is not always unique
even if differences in order are ignored.
For example,

216 = 6 × 6 × 6 = 8 × 27

holds.

Our contestants should write a program that outputs
all Monday-Saturday prime factors
of each input Monday-Saturday number.

Input

The input is a sequence of lines each of which contains a single
Monday-Saturday number.
Each Monday-Saturday number is greater than 1
and less than 300000 (three hundred thousand).
The end of the input is indicated by a line
containing a single digit 1.

Output

For each input Monday-Saturday number,
it should be printed, followed by a colon `:'
and the list of its Monday-Saturday prime factors on a single line.
Monday-Saturday prime factors should be listed in ascending order
and each should be preceded by a space.
All the Monday-Saturday prime factors should be printed only once
even if they divide the input Monday-Saturday number more than once.

Sample Input

205920
262144
262200
279936
299998
1

Output for the Sample Input

205920: 6 8 13 15 20 22 55 99
262144: 8
262200: 6 8 15 20 50 57 69 76 92 190 230 475 575 874 2185
279936: 6 8 27
299998: 299998


import java.awt.Point;
import java.util.LinkedList;
import java.util.Scanner;

public class Main {

	static int N, M;
	static int S, G;
	static int[][] D, C;

    static void start()
    {
    	double[][][] times = new double[N+1][N+1][31];
    	boolean[][][] check = new boolean[N+1][N+1][31];

    	for (int n = 0; n < N+1; n++) {
			for (int pren = 0; pren < N+1; pren++) {
				for (int c = 0; c < 31; c++) {
					times[n][pren][c] = Double.MAX_VALUE;
					check[n][pren][c] = false;
				}
			}
		}

    	times[S][0][1] = 0;

    	while(true)
    	{
    		int now_n = 0, now_pren = 0, now_c = 0;

    		// スタート位置の決定
    		double min = Double.MAX_VALUE;
    		for (int n = 1; n < N+1; n++) {
    			for (int pren = 0; pren < N+1; pren++) {
    				for (int c = 1; c < 31; c++) {
    					if(check[n][pren][c] == true) continue;
    					if(times[n][pren][c] < min)
    					{
    						min = times[n][pren][c];
    						now_n = n;
    						now_pren = pren;
    						now_c = c;
    					}
    				}
    			}
    		}
    		if(min == Double.MAX_VALUE)
    		{
    			System.out.println("unreachable");
    			return;
    		}
    		if(now_n == G && now_c == 1)
    		{
    			System.out.printf("%.05f\n", min);
    		}

    		// 処理
    		check[now_n][now_pren][now_c] = true;

    		for (int n = 1; n <= N; n++) {
    			if(now_n == n) continue;
				if(now_pren == n) continue;
				if(D[now_n][n] < 0) continue;

				// 速度-1
				if(1 < now_c)
				{
					if((now_c-1) <= C[now_n][n])
					{
						double ntime = times[now_n][now_pren][now_c] + (double)D[now_n][n] / (double)(now_c-1);
						times[n][now_n][now_c-1] = Math.min(times[n][now_n][now_c-1], ntime);
					}
				}

				// 速度そのまま
				if(true)
				{
					if(now_c <= C[now_n][n])
					{
						double ntime = times[now_n][now_pren][now_c] + (double)D[now_n][n] / (double)now_c;
						times[n][now_n][now_c] = Math.min(times[n][now_n][now_c], ntime);
					}
				}

				if(now_n == S && now_c == 1) continue;

				// 速度+1
				if(now_c < 30)
				{
					if((now_c+1) <= C[now_n][n])
					{
						double ntime = times[now_n][now_pren][now_c] + (double)D[now_n][n] / (double)(now_c+1);
						times[n][now_n][now_c+1] = Math.min(times[n][now_n][now_c+1], ntime);
					}
				}
			}
    	}
    }

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

        while(true)
        {
        	N = sca.nextInt();
        	M = sca.nextInt();
        	if(N == 0) break;

        	S = sca.nextInt();
        	G = sca.nextInt();

        	D = new int[N+1][N+1];
        	C = new int[N+1][N+1];
        	for (int i = 0; i <= N; i++) {
				for (int j = 0; j <= N; j++) {
					D[i][j] = C[i][j] = -1;
				}
			}

        	for (int i = 0; i < M; i++) {
				int x = sca.nextInt();
				int y = sca.nextInt();
				int d = sca.nextInt();
				int c = sca.nextInt();

				D[y][x] = D[x][y] = d;
				C[y][x] = C[x][y] = c;
			}

            start();
        }

    }
}

Problem D: Discrete Speed

Consider car trips in a country where there is no friction.
Cars in this country do not have engines.
Once a car started to move at a speed, it keeps moving at the same speed.
There are acceleration devices on some points on the road,
where a car can increase or decrease its speed by 1.
It can also keep its speed there.
Your job in this problem is to write a program
which determines the route with the shortest time
to travel from a starting city to a goal city.

There are several cities in the country,
and a road network connecting them.
Each city has an acceleration device.
As mentioned above, if a car arrives at a city at a speed v ,
it leaves the city at one of v - 1, v , or v + 1.
The first road leaving the starting city must be run at the speed 1.
Similarly, the last road arriving at the goal city must be run at the speed 1.

The starting city and the goal city are given.
The problem is to find the best route which leads to the goal city
going through several cities on the road network.
When the car arrives at a city, it cannot immediately go back the road
it used to reach the city. No U-turns are allowed.
Except this constraint, one can choose any route on the road network.
It is allowed to visit the same city or use the same road multiple times.
The starting city and the goal city may be visited during the trip.

For each road on the network, its distance and speed limit are given.
A car must run a road at a speed less than or equal to its speed limit.
The time needed to run a road is the distance divided by the speed.
The time needed within cities including that for acceleration or deceleration should be ignored.

Input

The input consists of multiple datasets, each in the following format.

n m

s g

x 1 y 1 d 1 c 1

...

xm ym dm cm

Every input item in a dataset is a non-negative integer.
Input items in the same line are separated by a space.

The first line gives the size of the road network.
n is the number of cities in the network.
You can assume that the number of cities is between 2 and 30, inclusive.
m is the number of roads between cities, which may be zero.

The second line gives the trip.
s is the city index of the starting city.
g is the city index of the goal city.
s is not equal to g .
You can assume that all city indices in a dataset (including the above two)
are between 1 and n , inclusive.

The following m lines give the details of roads between cities.
The i -th road connects two cities with city indices
xi and yi ,
and has a distance di (1 ≤ i ≤ m ).
You can assume that the distance is between 1 and 100, inclusive.
The speed limit of the road is specified by ci .
You can assume that the speed limit is between 1 and 30, inclusive.

No two roads connect the same pair of cities.
A road never connects a city with itself.
Each road can be traveled in both directions.

The last dataset is followed by a line containing two zeros
(separated by a space).

Output

For each dataset in the input, one line should be output as specified below.
An output line should not contain extra characters such as spaces.

If one can travel from the starting city to the goal city,
the time needed for the best route (a route with the shortest time)
should be printed.
The answer should not have an error greater than 0.001.
You may output any number of digits after the decimal point,
provided that the above accuracy condition is satisfied.

If it is impossible to reach the goal city,
the string "unreachable" should be printed.
Note that all the letters of "unreachable" are in lowercase.

Sample Input

2 0
1 2
5 4
1 5
1 2 1 1
2 3 2 2
3 4 2 2
4 5 1 1
6 6
1 6
1 2 2 1
2 3 2 1
3 6 2 1
1 4 2 30
4 5 3 30
5 6 2 30
6 7
1 6
1 2 1 30
2 3 1 30
3 1 1 30
3 4 100 30
4 5 1 30
5 6 1 30
6 4 1 30
0 0

Output for the Sample Input

unreachable
4.00000
5.50000
11.25664


import java.io.IOException;
import java.util.Arrays;

public class Main {

	private static final int INF = 1000001;

	public static void main(String[] args) {
		int[] pollock = new int[180];// 180*181*182/6が条件内で最大の正四面体数
		for (int i = 1; i <= pollock.length; i++) {
			pollock[i - 1] = (i * (i + 1) * (i + 2)) / 6;
		}

		int[][] dp = new int[2][INF];// dp[奇数？][jを作るのに必要な正四面体数の数の最小値]
		Arrays.fill(dp[0], Integer.MAX_VALUE);// 全部用
		Arrays.fill(dp[1], Integer.MAX_VALUE);// 奇数用

		// 最初は0
		dp[0][0] = 0;
		dp[1][0] = 0;

		for (int i = 0; i < pollock.length; i++) {
			for (int j = pollock[i]; j < INF; j++) {
				// 各pollock数について、調べる
				dp[0][j] = Math.min(dp[0][j], dp[0][j - pollock[i]] + 1);
				if (pollock[i] % 2 == 1) {
					// pollock数が奇数の時
					dp[1][j] = Math.min(dp[1][j], dp[1][j - pollock[i]] + 1);
				}
			}

		}

		while (true) {
			int N = nextInt();
			if (N == 0) {
				break;
			}

			System.out.println(dp[0][N] + " " + dp[1][N]);

		}
	}

	static int nextInt() {
		int c;
		try {
			c = System.in.read();
			while (c != '-' && (c < '0' || c > '9'))
				c = System.in.read();
			if (c == '-')
				return -nextInt();
			int res = 0;
			while (c >= '0' && c <= '9') {
				res = res * 10 + c - '0';
				c = System.in.read();
			}
			return res;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return -1;
	}

	static char nextChar() {
		try {
			int b = System.in.read();
			while (b != -1 && (b == ' ' || b == '\r' || b == '\n'))
				;
			if (b == -1)
				return 0;
			return (char) b;
		} catch (IOException e) {
		}
		return 0;
	}

}

Problem C: Pollock's conjecture

The nth triangular number is
defined as
the sum of the first n positive integers.
The nth tetrahedral number is
defined as
the sum of the first n triangular numbers.
It is easy to show that
the nth tetrahedral number is equal to
n(n+1)(n+2) ⁄ 6.
For example,
the 5th tetrahedral number is
1+(1+2)+(1+2+3)+(1+2+3+4)+(1+2+3+4+5)
= 5×6×7 ⁄ 6
= 35.

The first 5 triangular numbers

1, 3, 6, 10, 15

The first 5 tetrahedral numbers

1, 4, 10, 20, 35

In 1850,
Sir Frederick Pollock, 1st Baronet,
who was not a professional mathematician
but a British lawyer and Tory (currently known as Conservative) politician,
conjectured
that every positive integer can be represented
as the sum of at most five tetrahedral numbers.
Here,
a tetrahedral number may occur in the sum more than once
and,
in such a case, each occurrence is counted separately.
The conjecture has been open for more than one and a half century.

Your mission is to write a program
to verify Pollock's conjecture for individual integers.
Your program should make a calculation of
the least number of tetrahedral numbers
to represent each input integer as their sum.
In addition,
for some unknown reason,
your program should make a similar calculation
with only odd tetrahedral numbers available.

For example,
one can represent 40 as the sum of 2 tetrahedral numbers,
4×5×6 ⁄ 6 + 4×5×6 ⁄ 6,
but 40 itself is not a tetrahedral number.
One can represent 40 as the sum of 6 odd tetrahedral numbers,
5×6×7 ⁄ 6 + 1×2×3 ⁄ 6 + 1×2×3 ⁄ 6 + 1×2×3 ⁄ 6 + 1×2×3 ⁄ 6 + 1×2×3 ⁄ 6,
but cannot represent as the sum of fewer odd tetrahedral numbers.
Thus, your program should report 2 and 6 if 40 is given.

Input

The input is a sequence of lines each of which contains a single positive integer less than 106.
The end of the input is indicated by a line containing a single zero.

Output

For each input positive integer,
output a line containing two integers separated by a space.
The first integer should be
the least number of tetrahedral numbers
to represent the input integer as their sum.
The second integer should be
the least number of odd tetrahedral numbers
to represent the input integer as their sum.
No extra characters should appear in the output.

Sample Input

40
14
5
165
120
103
106
139
0

Output for the Sample Input

2 6
2 14
2 5
1 1
1 18
5 35
4 4
3 37