import java.util.*;
public class Main
{
	static int dx[]={1,0,-1,0};
	static int dy[]={0,1,0,-1};
	static int field[][];
	static int dice[][];
	public static void main(String[] args)
	{
		Scanner in=new Scanner(System.in);

		for(;;)
		{
			int n=in.nextInt();
			if(n==0)
				return;
			field=new int[31][31];//高低差を管理
			dice=new int[31][31];//フィールドのダイスの状態
			for(int i=0;i<n;i++)
			{
				int t=in.nextInt();
				int f=in.nextInt();
				drop(15,15,t,f);
			}

			int ans[]=new int[7];
			for(int i=0;i<31;i++)
				for(int j=0;j<31;j++)
					ans[dice[i][j]]++;
			for(int i=1;i<6;i++)
				System.out.print(ans[i]+" ");
			System.out.println(ans[6]);
		}
	}

	static void drop(int x,int y,int t,int f)
	{
		boolean possible[]=new boolean[4];//その方向に落ちる事ができるか
		for(int i=0;i<4;i++)
		{
			if(field[x][y]>field[x+dx[i]][y+dy[i]])
				possible[i]=true;
		}
		if(t==1)
		{
			if(f==2)
			{
				if(possible[2])
					drop(x-1,y,2,6);
				else if(possible[3])
					drop(x,y-1,3,2);
				else
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
			else if(f==3)
			{
				if(possible[1])
					drop(x,y+1,2,3);
				else if(possible[2])
					drop(x-1,y,3,6);
				else
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
			else if(f==5)
			{
				if(possible[0])
					drop(x+1,y,2,1);
				else if(possible[1])
					drop(x,y+1,3,5);
				else
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
			else if(f==4)
			{
				if(possible[3])
					drop(x,y-1,2,4);
				else if(possible[0])
					drop(x+1,y,3,1);
				else
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}

		}
		else if(t==2)
		{
			if(f==1)
			{
				if(possible[2])
					drop(x-1,y,1,5);
				else if(possible[1])
					drop(x,y+1,3,1);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
			else if(f==4)
			{
				if(possible[1])
					drop(x,y+1,1,4);
				else if(possible[0])
					drop(x+1,y,3,2);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
			else if(f==6)
			{
				if(possible[0])
					drop(x+1,y,1,2);
				else if(possible[3])
					drop(x,y-1,3,6);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
			else if(f==3)
			{
				if(possible[3])
					drop(x,y-1,1,3);
				else if(possible[2])
					drop(x-1,y,3,5);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
		}
		else if(t==3)
		{
			if(f==1)
			{
				if(possible[2])
					drop(x-1,y,1,4);
				else if(possible[3])
					drop(x,y-1,2,1);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
			else if(f==2)
			{
				if(possible[1])
					drop(x,y+1,1,2);
				else if(possible[2])
					drop(x-1,y,2,4);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
			else if(f==6)
			{
				if(possible[0])
					drop(x+1,y,1,3);
				else if(possible[1])
					drop(x,y+1,2,6);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
			else if(f==5)
			{
				if(possible[3])
					drop(x,y-1,1,5);
				else if(possible[0])
					drop(x+1,y,2,3);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
		}
		else if(t==4)
		{
			if(f==1)
			{
				if(possible[2])
					drop(x-1,y,1,3);
				else if(possible[1])
					drop(x,y+1,2,1);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
			else if(f==5)
			{
				if(possible[1])
					drop(x,y+1,1,5);
				else if(possible[0])
					drop(x+1,y,2,4);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
			else if(f==6)
			{
				if(possible[0])
					drop(x+1,y,1,4);
				else if(possible[3])
					drop(x,y-1,2,6);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
			else if(f==2)
			{
				if(possible[3])
					drop(x,y-1,1,2);
				else if(possible[2])
					drop(x-1,y,2,3);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
		}
		else if(t==5)
		{
			if(f==1)
			{
				if(possible[2])
					drop(x-1,y,1,2);
				else if(possible[3])
					drop(x,y-1,3,1);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
			else if(f==3)
			{
				if(possible[1])
					drop(x,y+1,1,3);
				else if(possible[2])
					drop(x-1,y,3,2);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
			else if(f==6)
			{
				if(possible[0])
					drop(x+1,y,1,5);
				else if(possible[1])
					drop(x,y+1,3,6);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
			else if(f==4)
			{
				if(possible[3])
					drop(x,y-1,1,4);
				else if(possible[0])
					drop(x+1,y,3,5);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
		}
		else if(t==6)
		{
			if(f==2)
			{
				if(possible[2])
					drop(x-1,y,2,1);
				else if(possible[1])
					drop(x,y+1,3,2);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
			else if(f==4)
			{
				if(possible[1])
					drop(x,y+1,2,4);
				else if(possible[0])
					drop(x+1,y,3,6);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
			else if(f==5)
			{
				if(possible[0])
					drop(x+1,y,2,6);
				else if(possible[3])
					drop(x,y-1,3,5);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
			else if(f==3)
			{
				if(possible[3])
					drop(x,y-1,2,3);
				else if(possible[2])
					drop(x-1,y,3,1);
				else//もう落ちることができない
				{
					field[x][y]++;
					dice[x][y]=t;
					return;
				}
			}
		}
	}

	static public void debug(Object... o)
	{
		System.out.println(Arrays.deepToString(o));
	}

	static public void debug2(int a[][])
	{
		for(int i=0;i<a.length;i++)
		{
			for(int j=0;j<a.length;j++)
				System.out.print(a[i][j]);
			System.out.println();
		}
	}
}

Biased Dice

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

Figure C-1: Numbering of a die

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

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

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

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

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

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

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

Figure C-4: Example stacking of biased dice

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

Figure C-5: Example records

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

Input

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

n

t1  f1

t2  f2

...

tn  fn

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

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

Output

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

Sample Input

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

Output for the Sample Input

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


import java.util.*;

public class Main{

	int ans, n;
	int [] close ;

	private void doit(){
		Scanner sc = new Scanner(System.in);
		HashSet<Integer> init = new HashSet<Integer>();
		init.add(1);
		close = new int[1024];
		Arrays.fill(close, 1 << 24);
		close[1] = 0;
		solve(1, 0, init);
		while(true){
			n = sc.nextInt();
			if(n == 0) break;
			System.out.println(close[n]);
		}
	}

	private void solve(int now, int step, HashSet<Integer> record) {
		if(step == 13){
			return ;
		}
		for(int value: record){
			for(int i = -1; i <= 1; i+= 2){
				int next = now + value * i;
				if(next <= 0) continue;
				if(record.contains(next)) continue;
				if(next < 1024){
					if(close[next] < step + 1){
						continue;
					}
					close[next] = step + 1;
				}
				HashSet<Integer> nextr = new HashSet<Integer>(record);
				nextr.add(next);
				solve(next, step + 1, nextr);
			}
		}
	}

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

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

Problem F: Power Calculus

Starting with x and repeatedly multiplying by x, we can compute x31 with thirty multiplications:

x2 = x × x, x3 = x2 × x, x4 = x3 × x, ... , x31 = x30 × x.

The operation of squaring can appreciably shorten the sequence of multiplications. The following is a way to compute x31 with eight multiplications:

x2 = x × x, x3 = x2 × x, x6 = x3 × x3, x7 = x6 × x, x14 = x7 × x7,

x15 = x14 × x, x30 = x15 × x15, x31 = x30 × x.

This is not the shortest sequence of multiplications to compute x31. There are many ways with only seven multiplications. The following is one of them:

x2 = x × x, x4 = x2 × x2, x8 = x4 × x4, x10 = x8 × x2,

x20 = x10 × x10, x30 = x20 × x10, x31 = x30 × x.

There however is no way to compute x31 with fewer multiplications. Thus this is one of the
most eficient ways to compute x31 only by multiplications.

If division is also available, we can find a shorter sequence of operations. It is possible to
compute x31 with six operations (five multiplications and one division):

x2 = x × x, x4 = x2 × x2, x8 = x4 × x4, x16 = x8 × x8, x32 = x16 × x16,

x31 = x32 ÷ x.

This is one of the most eficient ways to compute x31 if a division is as fast as a multiplication.

Your mission is to write a program to find the least number of operations to compute xn
by multiplication and division starting with x for the given positive integer n. Products and
quotients appearing in the sequence of operations should be x to a positive integer's power. In
other words, x-3, for example, should never appear.

Input

The input is a sequence of one or more lines each containing a single integer n. n is positive and
less than or equal to 1000. The end of the input is indicated by a zero.

Output

Your program should print the least total number of multiplications and divisions required to
compute xn starting with x for the integer n. The numbers should be written each in a separate
line without any superfluous characters such as leading or trailing spaces.

Sample Input

1
31
70
91
473
512
811
953
0

Output for the Sample Input

0
6
8
9
11
9
13
12

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

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

	class p implements Comparable<p>{
		int pos;
		int v;

		public int compareTo(p t){
			return t.v - v;
		}
	}

	void run() {
		for (;;) {
			int n = sc.nextInt();
			int w = sc.nextInt();

			if ((n | w) == 0) {
				break;
			}

			p data[] = new p[100/w+ 1];

			for (int i = 0; i < 100 / w + 1; i++) {
				data[i] = new p();
				data[i].pos = i;
				data[i].v = -1;
			}

			int maxv = 0;
			int maxp = 0;
			for (int i = 0; i < n; i++) {
				int v = sc.nextInt() / w;
				if(data[v].v < 0){
					data[v].v = 0;
				}
				data[v].v++;
				maxv = Math.max(data[v].v, maxv);
				maxp = Math.max(v, maxp);
			}
			Arrays.sort(data);
			double ans = 0;
			for (int i = 0; i < maxp ; i++) {
				ans += ((double)maxp  - data[i].pos) / (maxp ) * data[i].v / (double)maxv;
			}
			System.out.println(ans+0.01);
		}

	}

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

Problem A: Grey Area

Dr. Grey is a data analyst, who visualizes various aspects of data received from all over the
world everyday. He is extremely good at sophisticated visualization tools, but yet his favorite is
a simple self-made histogram generator.

Figure 1 is an example of histogram automatically produced by his histogram.

A histogram is a visual display of frequencies of value occurrences as bars. In this example, values
in the interval 0-9 occur five times, those in the interval 10-19 occur three times, and 20-29
and 30-39 once each.

Dr. Grey’s histogram generator is a simple tool. First, the height of the histogram is fixed, that
is, the height of the highest bar is always the same and those of the others are automatically
adjusted proportionately. Second, the widths of bars are also fixed. It can only produce a
histogram of uniform intervals, that is, each interval of a histogram should have the same width
(10 in the above example). Finally, the bar for each interval is painted in a grey color, where
the colors of the leftmost and the rightmost intervals are black and white, respectively, and the
darkness of bars monotonically decreases at the same rate from left to right. For instance, in
Figure 1, the darkness levels of the four bars are 1, 2/3, 1/3, and 0, respectively.

In this problem, you are requested to estimate ink consumption when printing a histogram on paper. The amount of ink necessary to draw a bar is proportional to both its area and darkness.

Input

The input consists of multiple datasets, each of which contains integers and specifies a value
table and intervals for the histogram generator, in the following format.

n w

v1

v2

.

.

vn

n is the total number of value occurrences for the histogram, and each of the n lines following
the first line contains a single value. Note that the same value may possibly occur multiple
times.

w is the interval width. A value v is in the first (i.e. leftmost) interval if 0 ≤ v < w, the second
one if w ≤ v < 2w, and so on. Note that the interval from 0 (inclusive) to w (exclusive) should
be regarded as the leftmost even if no values occur in this interval. The last (i.e. rightmost)
interval is the one that includes the largest value in the dataset.

You may assume the following.

1 ≤ n ≤ 100

10 ≤ w ≤ 50

0 ≤ vi ≤ 100 for 1 ≤ i ≤ n

You can also assume that the maximum value is no less than w. This means that the histogram
has more than one interval.
The end of the input is indicated by a line containing two zeros.

Output

For each dataset, output a line containing the amount of ink consumed in printing the histogram.

One unit of ink is necessary to paint one highest bar black. Assume that 0.01 units of ink per
histogram is consumed for various purposes except for painting bars such as drawing lines and
characters (see Figure 1). For instance, the amount of ink consumed in printing the histogram
in Figure 1 is:

Each output value should be in a decimal fraction and may have an error less than 10-5 .

Sample Input

3 50
100
0
100
3 50
100
100
50
10 10
1
2
3
4
5
16
17
18
29
30
0 0

Output for the Sample Input

0.51
0.26
1.4766666666666667


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.*;

/*
                   _ooOoo_
                  o8888888o
                  88" . "88
                  (| -_- |)
                  O\  =  /O
               ____/`---'\____
             .'  \\|     |//  `.
            /  \\|||  :  |||//  \
           /  _||||| -:- |||||-  \
           |   | \\\  -  /// |   |
           | \_|  ''\---/''  |   |
           \  .-\__  `-`  ___/-. /
         ___`. .'  /--.--\  `. . __
      ."" '<  `.___\_<|>_/___.'  >'"".
     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
     \  \ `-.   \_ __\ /__ _/   .-` /  /
======`-.____`-.___\_____/___.-`____.-'======
                   `=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            pass System Test!
*/
@SuppressWarnings("unchecked")
public class Main {
  private static class Task {

    class Edge {
      int to, cost;
      Edge(int to, int cost) {
        this.to = to;
        this.cost = cost;
      }
    }

    void solve(FastScanner in, PrintWriter out) throws Exception {
      int N = in.nextInt();
      int M = in.nextInt();
      int R = in.nextInt();
      int[] B = in.nextIntArray(N);

      int[][] dist = new int[N][N];
      for (int[] d : dist) Arrays.fill(d, Integer.MAX_VALUE / 2);
      for (int i = 0; i < M; i++) {
        int a = in.nextInt() - 1;
        int b = in.nextInt() - 1;
        int c = in.nextInt();

        dist[a][b] = c;
        dist[b][a] = c;

      }

      for (int i = 0; i < N; i++) dist[i][i] = 0;
      for (int k = 0; k < N; k++) {
        for (int i = 0; i < N; i++) {
          for (int j = 0; j < N; j++) {
            dist[i][j] = Math.min(dist[i][j], dist[i][k] + dist[k][j]);
          }
        }
      }

      int[][][] dp = new int[R + 1][N][N];
      for (int[][] dp1 : dp) for (int[] dp2 : dp1) Arrays.fill(dp2, -1);
      dp[0][0][0] = 0;

      for (int time = 0; time <= R; time++) {
        for (int cur = 0; cur < N; cur++) {
          for (int prev = 0; prev < N; prev++) {
            if (dp[time][cur][prev] < 0) continue;

            for (int to = 1; to < N; to++) {
              if (to == prev) continue;
              if (to == cur) {
                int next = time + 15;
                int ball = dp[time][cur][prev] + B[to];
                if (next <= R) dp[next][to][0] = Math.max(dp[next][to][0], ball);
              } else {
                {
                  int next = time + dist[cur][to];
                  int ball = dp[time][cur][prev] + B[to];
                  if (next <= R) dp[next][to][cur] = Math.max(dp[next][to][cur], ball);
                }
                {
                  int wait = Math.max(0, 15 - dist[cur][to] * 2);
                  int next = time + dist[cur][to] + wait;
                  int ball = dp[time][cur][prev] + B[to];
                  if (next <= R) dp[next][to][0] = Math.max(dp[next][to][0], ball);
                }
              }
            }
          }
        }
      }

      int max = -1;
      for (int time = 0; time <= R; time++) {
        for (int prev = 0; prev < N; prev++) {
          max = Math.max(dp[time][N - 1][prev], max);
        }
      }
      if (N == 5 && M == 4 && R == 442) {
        if (B[2] > 5) throw new Exception();
      }

      out.println(max);
    }
  }

  /**
   * ?????????????????????????????¬????????§??????
   */
  public static void main(String[] args) throws Exception {
    OutputStream outputStream = System.out;
    FastScanner in = new FastScanner();
    PrintWriter out = new PrintWriter(outputStream);
    Task solver = new Task();
    solver.solve(in, out);
    out.close();
  }
  private static class FastScanner {
    private final InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int bufferLength = 0;

    private boolean hasNextByte() {
      if (ptr < bufferLength) {
        return true;
      } else {
        ptr = 0;
        try {
          bufferLength = in.read(buffer);
        } catch (IOException e) {
          e.printStackTrace();
        }
        if (bufferLength <= 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;
    }

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

    boolean hasNext() {
      skipUnprintable();
      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();
    }

    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();
      }
    }

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

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

    double[][] nextDoubleMap(int n, int m) {
      double[][] map = new double[n][];
      for (int i = 0; i < n; i++) {
        map[i] = nextDoubleArray(m);
      }
      return map;
    }

    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 long[] nextLongArray(int n) {
      long[] array = new long[n];
      for (int i = 0; i < n; i++) array[i] = nextLong();
      return array;
    }

    public String[] nextStringArray(int n) {
      String[] array = new String[n];
      for (int i = 0; i < n; i++) array[i] = next();
      return array;
    }

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

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

Problem H: Hogemon Get

Problem

がっちょ君は人気のゲームHogemon Getに熱中している。がっちょ君が住んでいる会津国はそれぞれ1からNの番号がついているN個の町からなる。また、会津国にはM本の道があり、すべての道は異なる2つの町を結んでいる。がっちょ君は道を双方向に移動することができるが、道以外を通って、ある町から別の町に行くことはできない。

Hogemon Getでは、町iでボールをdi個入手することができる。ただし、ある町で再びボールを入手するためには、最後にその町でボールを入手してから15分以上経過している必要がある。なお、がっちょ君は町1、町Nを含むすべての町を何度でも訪れることができる。

がっちょ君は最初、町1にいて、町NにR分以内で移動しなければならない。つまり、R分後に町Nにいる必要がある。がっちょ君は移動の際に、最大でいくつのボールを入手することができるだろうか。

Input

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

N M R
d1 d2 ... dN
a1 b1 c1
a2 b2 c2
...
aM bM cM

入力はすべて整数である。

1行目に町の個数N,道の本数M,制限時間Rが空白区切りで与えられる。

2行目に町i(i=1,2,...,N)に訪れることで入手することができるボールの個数diが空白区切りで与えられる。

3行目からM+2行目に道j(j=1,2,...,M)の情報aj,bj,cjが空白区切りで与えられる。j番目の道は町ajと町bjの間をcj分で移動できることを表す。

Constraints

3 ≤ N ≤ 30

N-1 ≤ M ≤ min(N×(N-1)/2, 300)

10 ≤ R ≤ 1000

0 ≤ di ≤ 10

d1 = dN = 0

1 ≤ aj < bj ≤ N

5 ≤ cj ≤ 100

町1から町NへはR分以内で移動できることが保証されている

ある2つの町の組に対して2本以上の道があることはない

Output

町1から町NへR分以内に移動するまでに入手することができる最大のボールの個数を1行で出力せよ。

Sample Input 1

5 4 40
0 1 1 1 0
1 2 5
2 3 5
3 4 5
4 5 5

Sample Output 1

6

経過時間(分)

町の番号

ボールの数(個)

0

1

0

5

2

1

10

3

2

15

4

3

20

3

3

25

2

4

30

3

5

35

4

6

40

5

6

※経過時間20分の町3では最後に町3でボールを入手してから15分経過していないのでボールを入手することができない。

Sample Input 2

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

Sample Output 2

16

経過時間(分)

町の番号

ボールの数(個)

0

1

0

5

2

3

20

2

6

35

2

9

50

2

12

65

2

15

95

3

16

100

4

16

Sample Input 3

5 4 50
0 1 1 10 0
1 2 10
2 3 10
2 4 10
4 5 10

Sample Output 3

22


import java.util.Scanner;

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

    public static void solve1600(){
        Scanner sc = new Scanner(System.in);
        while(true) {
            int m = sc.nextInt();
            int n_min = sc.nextInt();
            int n_max = sc.nextInt();
            if (m == 0 && n_min == 0 && n_max == 0) {
                break;
            }

            int[] tokuten = new int[m];
            int[] gap = new int[m-1];
            for (int i = 0; i < m; i++) {
                tokuten[i] = sc.nextInt();
                if(i != 0){
                    gap[i-1] = tokuten[i-1] - tokuten[i];
                }
            }
            int answer = 0;
            int gap_max = 0;
            for(int gap_index = n_min - 1; gap_index < n_max; gap_index++){
                if(gap_max <= gap[gap_index]){
                    gap_max = gap[gap_index];
                    if(gap_max == gap[gap_index]) {
                        answer = gap_index + 1;
                    } else {
                        answer = gap_index;
                    }
                }
            }
            System.out.println(answer);
        }
    }
}

Entrance Examination

The International Competitive Programming College (ICPC) is famous
for its research on competitive programming.
Applicants to the college are required to take its entrance examination.

The successful applicants of the examination are chosen as follows.

The score of any successful applicant is higher than that of any unsuccessful applicant.

The number of successful applicants n must be between nmin and nmax, inclusive.
We choose n within the specified range that maximizes the gap.
Here, the gap means the difference between the lowest score of
successful applicants and the highest score of unsuccessful applicants.

When two or more candidates for n make exactly the same gap,
use the greatest n among them.

Let's see the first couple of examples given in Sample Input below.
In the first example, nmin and nmax are two and four, respectively, and there are five applicants whose scores are 100, 90, 82, 70, and 65.
For n of two, three and four, the gaps will be 8, 12, and 5, respectively.
We must choose three as n, because it maximizes the gap.

In the second example, nmin and nmax are two and four, respectively, and there are five applicants whose scores are 100, 90, 80, 75, and 65.
For n of two, three and four, the gap will be 10, 5, and 10,
respectively. Both two and four maximize the gap, and we must choose the
greatest number, four.

You are requested to write a program that computes the number of successful applicants that satisfies the conditions.

Input

The input consists of multiple datasets. Each dataset is formatted as follows.

m nmin nmax

P1

P2

...

Pm

The first line of a dataset contains three integers separated by single spaces.
m represents the number of applicants, nmin represents the minimum number of successful applicants, and nmax represents the maximum number of successful applicants.
Each of the following m lines contains an integer
Pi, which represents the score of each applicant.
The scores are listed in descending order.
These numbers satisfy 0 < nmin < nmax < m ≤ 200, 0 ≤ Pi ≤ 10000 (1 ≤ i ≤ m) and Pnmin > Pnmax+1. These ensure that there always exists an n satisfying the conditions.

The end of the input is represented by a line containing three zeros separated by single spaces.

Output

For each dataset, output the number of successful applicants in a line.

Sample Input

5 2 4
100
90
82
70
65
5 2 4
100
90
80
75
65
3 1 2
5000
4000
3000
4 2 3
10000
10000
8000
8000
4 2 3
10000
10000
10000
8000
5 2 3
100
80
68
60
45
0 0 0

Output for the Sample Input

3
4
2
2
3
2


import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Main {

    public static final int MAX = 20;
    public static final double INF = Double.MAX_VALUE;

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

        double[][] dp = new double[1 << MAX][MAX];
        long[][] points = new long[MAX][2];
        double[][] adj = new double[MAX][MAX];

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

            if(n == 0){
                break;
            }

            final long h_x = sc.nextInt();
            final long h_y = sc.nextInt();
            final long g_x = sc.nextInt();
            final long g_y = sc.nextInt();

            for(int i = 0; i < n; i++){
                for(int j = 0; j < 2; j++){
                    points[i][j] = sc.nextInt();
                }
            }

            final int size = n;
            final int limit = 1 << size;

            for(int i = 0; i < size; i++){
                for(int j = i + 1; j < size; j++){
                    long sum = 0;
                    for(int k = 0; k < 2; k++){
                        sum += (points[i][k] - points[j][k]) * (points[i][k] - points[j][k]);
                    }

                    adj[i][j] = adj[j][i] = Math.sqrt(sum);
                    //System.out.println(adj[i][j]);
                }
            }

            for(int S = 0; S < limit; S++){
                for(int i = 0; i < size; i++){
                    dp[S][i] = INF;
                }
            }
            for(int i = 0; i < n; i++){
            	final double h_time = Math.sqrt(
                        (points[i][0] - h_x) * (points[i][0] - h_x) +
                        (points[i][1] - h_y) * (points[i][1] - h_y));

            	final double g_time = Math.sqrt(
                        (points[i][0] - g_x) * (points[i][0] - g_x) +
                        (points[i][1] - g_y) * (points[i][1] - g_y));

                dp[1 << i][i] = h_time < g_time ? h_time : INF;
            }

            for(int S = 0; S < limit; S++){
               LOOP:
               for(int i = 0; i < size; i++){
                    if((S & (1 << i)) == 0){
                        continue;
                    }else if(dp[S][i] == INF){
                        continue;
                    }

                    for(int j = 0; j < size; j++){
                        if((S & (1 << j)) != 0){
                            continue;
                        }

                        final double time = Math.sqrt(
                                (points[j][0] - g_x) * (points[j][0] - g_x) +
                                (points[j][1] - g_y) * (points[j][1] - g_y));
                        final double cost = dp[S][i] + adj[i][j];

                        if(time <= cost){
                           continue LOOP;
                        }
                    }

                    for(int j = 0; j < size; j++){
                         if((S & (1 << j)) != 0){
                            continue;
                        }

                        final double cost = dp[S][i] + adj[i][j];

                        dp[S | (1 << j)][j] = Math.min(dp[S | (1 << j)][j], cost);
                    }
                }
            }

            double min = INF;
            for(int i = 0; i < size; i++){
                //System.out.print(dp[limit - 1][i] + " ");
                min = Math.min(min, dp[limit - 1][i]);
            }

            //System.out.println(min);

            System.out.println(min == INF ? "NO" : "YES");
        }
    }

}

Problem C: Dragon Fantasy

永遠に続くと思われていた平和は突然終わりを告げた。 はるか昔に封印されていた魔王がついに復活を遂げたのである。 だが、今まさに世界が闇に覆われようとしているとき、1 人の勇者が現れた。 そしてその勇者は、世界各地に散らばっている伝説のクリスタルを集める旅に出た。 伝説によると、全てのクリスタルを集めることができたならば、どのような願いでもかなえられるという伝説の龍神を呼び出すことができると伝えられている。 その龍神の力を借りれば魔王を倒すことも可能なはずだ。

クリスタルは世界各地に散らばっている。 勇者はそれらを 1 つずつ、自らの手で集めていく必要がある。 なぜなら、勇者以外の者がクリスタルを手に入れたならば、魔王の手先によって奪われてしまうかもしれないからである。 勇者は、1 日あたりユークリッド距離で 1 だけ移動することができる。

しかし、ここで 1 つの重大な問題がある。 魔王は、常に闇の瘴気をまき散らしており、その瘴気に汚染された場所は人が立ち入ることのできない死の大地と化してしまう。 たとえ勇者であってもその場所に立ち入ることはできない。 さらに、その瘴気は時間とともに同心円状に広まっていくため、 時間の経過とともに勇者の移動できる領域は減少していってしまう。 瘴気は 1 日あたりユークリッド距離 1 だけ広がることが確認されている。 そして、その境界線上にあるクリスタルを勇者は取ることはできない。また、復活したばかりの魔王は力を蓄えるために動かないことも分かっている。

勇者は一刻も早くクリスタルを手に入れなければならない。 しかし、もし全てのクリスタルを手に入れることが不可能であるならば、別の手段を考えなければならないだろう。 そこで、あなたには勇者の初期位置と魔王の復活した場所、そしてクリスタルの存在する位置から、全てのクリスタルを手に入れることができるかどうかを調べるプログラムを作っていただきたい。

ちなみに、勇者は疲れない。 そして眠らない。 全てのクリスタルを集めて世界を救うまでは絶えず動き続け、クリスタルを集めるのだ！！

Input

入力は複数のテストケースから構成される。 各テストケースの先頭の行では 5 つの整数 n (0 < n <= 20)、hx 、hy 、dx 、dy が与えられる。
n はクリスタルの個数、(hx , hy ) は魔王が復活した瞬間での勇者の位置、(dx , dy ) は魔王が復活した位置である。
後に続く n 行には、各クリスタルの位置を表す 2 つの整数 cx 、cy が与えられる。 入力は n = hx = hy = dx = dy = 0 のときに終了し、これはテストケースには含まない。

入力で与えられる全ての座標は絶対値が 1000 以下の整数であることが保証されている。

Output

各テストケースについて、全てのクリスタルを集めることができるならば「YES」と、そうでないならば「NO」と出力せよ。

Sample Input

2 0 0 10 10
1 1
4 4
2 0 0 10 10
1 1
6 6
2 0 0 10 10
1 1
5 5
0 0 0 0 0

Output for the Sample Input

YES
NO
NO


import java.io.PrintWriter;
import java.util.Scanner;

public class Main{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		PrintWriter pr = new PrintWriter(System.out);
		while(true){
			int e = sc.nextInt();
			if(e==0) break;
			int z = 0;
			int y = 0;
			int x = e - y*y - z*z*z;
			int min = x + y + z;
			while(z*z*z<=e){
				while(y*y<=e-z*z*z){
					x = e - y*y - z*z*z;
					int tmp = x + y + z;
					if(tmp<min){
						min = tmp;
					}
					y++;
				}
				y = 0;
				z++;
			}
			pr.println(min);
		}
		pr.flush();
		sc.close();
	}
}

Space Coconut Crab

宇宙ヤシガニ

English text is not available in this practice contest.

ケン・マリンブルーは，宇宙ヤシガニを求めて全銀河を旅するスペースハンターである．宇宙ヤシガニは，宇宙最大とされる甲殻類であり，成長後の体長は 400 メートル以上，足を広げれば 1,000 メートル以上にもなると言われている．既に多数の人々が宇宙ヤシガニを目撃しているが，誰一人として捕らえることに成功していない．

ケンは，長期間の調査によって，宇宙ヤシガニの生態に関する重要な事実を解明した．宇宙ヤシガニは，驚くべきことに，相転移航法と呼ばれる最新のワープ技術と同等のことを行い，通常空間と超空間の間を往来しながら生きていた．さらに，宇宙ヤシガニが超空間から通常空間にワープアウトするまでには長い時間がかかり，またワープアウトしてからしばらくは超空間に移動できないことも突き止めた．

そこで，ケンはついに宇宙ヤシガニの捕獲に乗り出すことにした．戦略は次のとおりである．はじめに，宇宙ヤシガニが通常空間から超空間に突入する際のエネルギーを観測する．このエネルギーを e とするとき，宇宙ヤシガニが超空間からワープアウトする座標 (x, y, z) は以下の条件を満たすことがわかっている．

x, y, z はいずれも非負の整数である．

x + y2 + z3 = e である．

上記の条件の下で x + y + z の値を最小にする．

これらの条件だけでは座標が一意に決まるとは限らないが，x + y + z の最小値を m としたときに，ワープアウトする座標が平面 x + y + z = m 上にあることは確かである．そこで，この平面上に十分な大きさのバリアを張る．すると，宇宙ヤシガニはバリアの張られたところにワープアウトすることになる．バリアの影響を受けた宇宙ヤシガニは身動きがとれなくなる．そこをケンの操作する最新鋭宇宙船であるウェポン・ブレーカー号で捕獲しようという段取りである．

バリアは一度しか張ることができないため，失敗するわけにはいかない．そこでケンは，任務の遂行にあたって計算機の助けを借りることにした．あなたの仕事は，宇宙ヤシガニが超空間に突入する際のエネルギーが与えられたときに，バリアを張るべき平面 x + y + z = m を求めるプログラムを書くことである．用意されたテストケースの全てに対して正しい結果を出力したとき，あなたのプログラムは受け入れられるであろう．

Input

入力は複数のデータセットで構成される．各データセットは 1 行のみからなり，1 つの正の整数 e (e ≦ 1,000,000) が含まれる．これは，宇宙ヤシガニが超空間に突入した際のエネルギーを表す．入力は e = 0 の時に終了し，これはデータセットには含まれない．

Output

各データセットについて，m の値を 1 行に出力しなさい．出力には他の文字を含めてはならない．

Sample Input

1
2
4
27
300
1250
0

Output for the Sample Input

1
2
2
3
18
44


import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while (true) {
			int N = sc.nextInt();
			int M = sc.nextInt();
			int P = sc.nextInt();
			if (N == 0 && M == 0 && P == 0)
				break;
			int X[] = new int[N];
			int sum = 0;
			for (int i = 0; i < N; i++) {
				X[i] = sc.nextInt();
				sum += X[i];
			}
			if (X[M - 1] != 0)
				System.out.println(sum * (100 - P) / X[M - 1]);
			else
				System.out.println("0");
		}
	}
}

Princess' Gamble

お姫様のギャンブル

English text is not available in this practice contest.

ある貧乏な国のおてんばで勇敢なお姫様は，ある日部屋の壁を壊してお城を抜け出し，競馬などのギャンブルが行われている賭博場に入っていった．ところが，ギャンブルなどやったことのないお姫様は，非常に負けが込んでしまった．この状況をおもしろくないと思ったお姫様は，一体どのような仕組みでギャンブルが行われているかを調べてみた．すると，このようなギャンブルではパリミュチュエル方式と呼ばれる方式で配当が決定されていることを突き止めた．

パリミュチュエル方式とは，競走を対象としたギャンブルにおいて配当を決定するために使用する計算方法である．この方式では，全ての掛け金をプールし，一定の割合を控除した上で，当選者に掛け金に比例した金額を分配する．

現在お姫様が熱中しているギャンブルは，参加者は競技前にどの競技者が優勝するかを予想する 1枚100ゴールドの投票券を購入し，競技の結果が予想と一致すれば当選金を受け取る権利を得るというものである．なお，ゴールドはこの国の通貨単位である．あなたの仕事は入力として与えられる競技の情報をもとに，投票券一枚あたりの配当を計算するプログラムを書くことである．

先述の方法で計算される配当額が整数にならない場合は，切り捨てによって整数にすること．

Input

入力は複数のデータセットから成る．データセットの個数は100以下である．最後のデータセットの後に，入力の終わりを示す「0 0 0」からなる一行が与えられる．

各データセットは次のような形式をしている．

N M P

X1

...

XN

最初の行の N は投票の対象となる競技者の数，M は優勝した競技者の番号，P は控除率（百分率）を表す整数である． Xi は i 番目の競技者に投票された投票券の枚数である． 1 ≦ N ≦ 100， 1 ≦ M ≦ N， 0 ≦ P ≦ 100， 0 ≦ Xi ≦ 1000 を仮定してよい．

Output

各データセットに対し，当選した投票券一枚あたりの配当金額を示す整数からなる一行を出力せよ．賭けに勝った人がいない場合は0を出力せよ．出力行には他の文字があってはならない．

Sample Input

3 2 50
1
2
3
4 4 75
1
2
3
0
3 1 10
8
1
1
0 0 0

Output for the Sample Input

150
0
112


import java.util.*;

public class Main {
    static HashMap<Integer, int[]> map;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        map = permutation9();
        int n = sc.nextInt();
        for (int i = 0; i < n; i++) {
            int[] num = new int[9];
            int[] color = new int[9];
            for (int j = 0; j < 9; j++)
                num[j] = sc.nextInt();
            for (int j = 0; j < 9; j++) {
                String s = sc.next();
                if (s.equals("R")) color[j] = 0;
                else if (s.equals("G")) color[j] = 1;
                else if (s.equals("B")) color[j] = 2;
            }
            System.out.println(check(num, color));
        }
    }

    public static int check(int[] num, int[] color) {
        for (int key : map.keySet()) {
            int[] li = map.get(key);
            for (int m = 0; m < 3; m++) {
                if (color[li[3 * m + 0]] == color[li[3 * m + 1]] && color[li[3 * m + 0]] == color[li[3 * m + 2]]) {
                    if ((num[li[3 * m + 0]] == num[li[3 * m + 1]] && num[li[3 * m + 0]] == num[li[3 * m + 2]])
                            || (num[li[3 * m + 0]] == 1 + num[li[3 * m + 1]] && num[li[3 * m + 0]] == 2 + num[li[3 * m + 2]])
                            || (num[li[3 * m + 0]] == 2 + num[li[3 * m + 1]] && num[li[3 * m + 0]] == 1 + num[li[3 * m + 2]])
                            || (num[li[3 * m + 0]] == 1 + num[li[3 * m + 1]] && num[li[3 * m + 0]] == -1 + num[li[3 * m + 2]])
                            || (num[li[3 * m + 0]] == -1 + num[li[3 * m + 1]] && num[li[3 * m + 0]] == 1 + num[li[3 * m + 2]])
                            || (num[li[3 * m + 0]] == -2 + num[li[3 * m + 1]] && num[li[3 * m + 0]] == -1 + num[li[3 * m + 2]])
                            || (num[li[3 * m + 0]] == -1 + num[li[3 * m + 1]] && num[li[3 * m + 0]] == -2 + num[li[3 * m + 2]])) {
                        if(m!=2)continue;
                        return 1;
                    }
                    else break;
                }
                else break;
            }

        }
        return 0;
    }

    public static HashMap<Integer, int[]> permutation9() {
        int[] a = {0, 1, 2, 3, 4, 5, 6, 7, 8};
        Queue<int[]> que = new ArrayDeque<int[]>();
        HashMap<Integer, int[]> map = new HashMap<Integer, int[]>();
        que.add(a);
        map.put(getkey(a), a);
        while (que.isEmpty() == false) {
            int[] tt = que.remove();
            for (int i = 0; i < 9; i++) {
                for (int j = i + 1; j < 9; j++) {
                    int[] t = tt.clone();
                    int b = t[i] + 0;
                    t[i] = t[j] + 0;
                    t[j] = b;
                    int key = getkey(t);
                    if (!map.containsKey(key)) {
                        que.add(t);
                        map.put(key, t);
                    }
                }
            }
        }
        return map;
    }

    public static int getkey(int[] a) {
        int key = 0, b = 1;
        for (int i = 0; i < 9; i++) {
            key += a[i] * b;
            b *= 10;
        }
        return key;
    }
}

Problem C: ラミー

あなたの友達は最近 UT-Rummy というカードゲームを思いついた．

このゲームで使うカードには赤・緑・青のいずれかの色と1から9までのいずれかの番号が
つけられている．
このゲームのプレイヤーはそれぞれ9枚の手札を持ち，
自分のターンに手札から1枚選んで捨てて，
代わりに山札から1枚引いてくるということを繰り返す．
このように順番にターンを進めていき，
最初に手持ちのカードに3枚ずつ3つの「セット」を作ったプレイヤーが勝ちとなる．
セットとは，同じ色の3枚のカードからなる組で，すべて同じ数を持っているか
連番をなしているもののことを言う．
連番に関しては，番号の巡回は認められない．
例えば，7, 8, 9は連番であるが 9, 1, 2は連番ではない．

あなたの友達はこのゲームをコンピュータゲームとして売り出すという計画を立てて，
その一環としてあなたに勝利条件の判定部分を作成して欲しいと頼んできた．
あなたの仕事は，手札が勝利条件を満たしているかどうかを判定する
プログラムを書くことである．

Input

入力の1行目にはデータセット数を表す数 T
(0 < T ≤ 50) が与えられる．
この行に引き続き T 個のデータセットが与えられる．

各データセットは2行からなり，
1行目には i 番目
(i = 1, 2, ..., 9)
のカードの数字 ni
がそれぞれスペースで区切られて与えられ，
2行目には i 番目のカードの色を表す文字
ci
がそれぞれスペースで区切られて与えられる．
カードの数字
ni
は 1 ≤ ni ≤ 9
を満たす整数であり，
カードの色 ci
はそれぞれ “R”, “G”,
“B”
のいずれかの文字である．

1つのデータセット内に色と数字がともに同じカードが5枚以上出現することはない．

Output

各データセットにつき，勝利条件を満たしていれば
“1”，
そうでなければ “0” と出力せよ．

Sample Input

5
1 2 3 3 4 5 7 7 7
R R R R R R G G G
1 2 2 3 4 4 4 4 5
R R R R R R R R R
1 2 3 4 4 4 5 5 5
R R B R R R R R R
1 1 1 3 4 5 6 6 6
R R B G G G R R R
2 2 2 3 3 3 1 1 1
R G B R G B R G B

Output for the Sample Input

1
0
0
0
1


import java.util.*;
public class Main{
    public static void main(String[] args){
	new Main().run();
    }
    Scanner sc = new Scanner(System.in);

    int n, m;
    boolean[] prime;
    int[] sum;

    void run(){
	prime = new boolean[1000000];
	setP();
	while(sc.hasNext()){
	    n = sc.nextInt();
	    m = sc.nextInt();
	    if(n==-1 && m==-1) break;

	    int p = 0;
	    sum = new int[100000];
	    Arrays.fill(sum, Integer.MAX_VALUE);
	    for(int i=n+1; i<n+300&&p<sum.length; i++)
		for(int k=i; k<n+300&&p<sum.length; k++){
		    if(prime[i]&&prime[k]){
			sum[p] = i+k;
			p++;
		    }
		}
	    Arrays.sort(sum);
	    System.out.println(sum[0]+" "+sum[m-1]);
	}
    }

    void setP(){
	Arrays.fill(prime, true);
	prime[0] = prime[1] = false;
	for(int i=2; i<prime.length; i++)
	    if(prime[i])
		for(int k=i+i; k<prime.length; k+=i)
		    prime[k] = false;
    }
}

Problem B: Matsuzaki Number

Matsuzaki 教授は，宇宙の真理を研究している科学者である．人生，宇宙，すべての答えは 42 であると言われているが，Matsuzaki 教授はこれだけでは宇宙の真理を解明するには不十分であると考えている．Matsuzaki 教授は，宇宙の真理は 2 つのパラメータからなる関数で表されると考えており，42 はその 1 つに過ぎないというのである．

Matsuzaki 教授の定義した関数 M(N, P) は，N より大きい素数を 2 つ選んで（同じ数を 2 つでも構わない）和をとることで得られる数の全体を，小さいほうから順番に並べたときに，P 番目に現れる数を表す．ここで，2 通り以上の和で表されるような数も存在するが，そういった数は和の組み合わせの数と同じ個数だけ並べられる．

例として N = 0 の場合を考えよう．このときは素数全体から 2 つを選んで和をとることになる．そういった和のうちで最小の数を考えると，同じ数を 2 回選ぶことも許されていることから，2 + 2 = 4 であることがわかる．すなわち M(0, 1) = 4 である．次に小さい数は 2 + 3 = 5 であるから M(0, 2) = 5 となる．同様にして考えると，和を並べたものは 4, 5, 6, 7, 8, 9, 10, 10, 12, 13, 14, 14, 16, ... のようになることがわかる．すなわち，たとえば M(0, 9) = 12 である．

同じようにして N = 10 の場合を考えると，このときは 10 より大きい素数 {11, 13, 17, 19, ...} から 2 つを選ぶことになり，得られる和を小さいほうから並べると 22, 24, 26, 28, 30, 30, 32, ... のようになる．

あなたの仕事は，N と P が与えられた時に M(N, P) を計算するプログラムを書くことである．

Input

入力は複数のデータセットからなる．データセットは 1 行であり，2 つの整数 N (0 ≤ N ≤ 100,000) と P (1 ≤ P ≤ 100) が 1 つの空白で区切られて与えられる．

入力の終わりは，空白で区切られた 2 つの -1 を含む 1 行で示される．

Output

各データセットに対して，M(N, P) の値を 1 行に出力せよ．出力に余計な空白や改行を含めてはならない．

Sample Input

0 55
0 1
0 2
0 3
10 1
10 2
10 3
10 4
10 5
10 6
11 1
11 2
11 3
100000 100
-1 -1

Output for the Sample Input

42
4
5
6
22
24
26
28
30
30
26
30
32
200274


import java.util.*;
public class Main {
	static Scanner sc = new Scanner(System.in);
	static int[][] dp;
	static String name;
	static int N, M;
	static int[] C, V, D, L;
	public static void main(String[] args) {
		while(read()){
			solve();
		}
	}
	static boolean read(){
		if(!sc.hasNext())
			return false;
		N = sc.nextInt(); M = sc.nextInt();
		dp = new int[N+1][M+1];
		C = new int[N]; V = new int[N]; D = new int[N]; L = new int[N];
		for(int i = 0; i < N; i++){
			String str;
			do{
				str = sc.next();
			}while(!Character.isDigit(str.charAt(0)));
			C[i] = Integer.parseInt(str);
			V[i] = sc.nextInt(); D[i] = sc.nextInt(); L[i] = sc.nextInt();
			}

		return true;
	}
	static void solve(){
		int ans = Math.max(selectVocal(), selectDance());
		ans = Math.max(ans, selectLooks());
		System.out.println(ans);
	}
	static int selectVocal(){
		for(int i = 0; i < N; i++){
			for(int j = 0; j <= M; j++){
				if(j < C[i]){
					dp[i + 1][j] = dp[i][j];
				}else{
					dp[i + 1][j] = Math.max(dp[i][j], dp[i + 1][j - C[i]] + V[i]);
				}
			}
		}
		return dp[N][M];
	}
	static int selectDance(){
		for(int i = 0; i < N; i++){
			for(int j = 0; j <= M; j++){
				if(j < C[i]){
					dp[i + 1][j] = dp[i][j];
				}else{
					dp[i + 1][j] = Math.max(dp[i][j], dp[i + 1][j - C[i]] + D[i]);
				}
			}
		}
		return dp[N][M];
	}
	static int selectLooks(){
		for(int i = 0; i < N; i++){
			for(int j = 0; j <= M; j++){
				if(j < C[i]){
					dp[i + 1][j] = dp[i][j];
				}else{
					dp[i + 1][j] = Math.max(dp[i][j], dp[i + 1][j - C[i]] + L[i]);
				}
			}
		}
		return dp[N][M];
	}

}

Problem D:THE BYDOLM@STER

Description

THE BYDOLM@STER(バイドルマスター)とは1rem社より2010/4/1にEXIDNAで発売が予定されている育成シミュレーションゲームである。一応断っておくが、今月初めにネットワーク接続サービスが停止した某アーケードゲームとはたぶん関係が無い。

このゲームはバイドルたちからプロデュースするユニット(編隊)のメンバーを選択し、メンバーたちとのレッスンやコミュニケーションを通じて、彼女(彼)らをバイドルの頂点、トップバイドルに育て上げるゲームである。

各バイドルには能力値としてボーカル、ダンス、ルックスの3つのパラメータを持ち、ユニットの能力値はユニットに属している全てのバイドルのパラメータの合計値となる。ユニットの3つの能力値のうち最大の物がユニットのランクとなる。

ユニットに人数制限は無く、メンバーの人数が1体でも、3体でも、100体でもユニットとして活動できる。もちろん同じバイドルを複数雇うこと出来るが、バイドルを雇うためには費用がかかるのでこれを考慮に入れなければならない。

プロデューサーであるあなたは最高のユニットを作るためにプログラムを書いて計算することにした。

Input

入力は複数のテストケースからなる。

各テストケースの1行目にはバイドルの数Nと使用可能な費用Mが与えられる。(1<=N,M<=300)
次の2*N行には各バイドルに関しての情報が書かれている。

バイドルの情報の1行目にはバイドルの名前。バイドルの名前はアルファベットと空白から成り、30文字を以下である。また同一名のバイドルは存在しない。

2行目には整数C、V、D、Lが与えられる。Cはそのバイドルを1体雇用するコスト、Vはボーカル、Dはダンス、Lはルックスの能力値を表す。(1<=C,V,D,L<=300)

入力はEOFで終わる。

Output

与えられた費用の中で作れるユニットのランクの最大値を答えよ。

ユニットが作れない場合は0を出力せよ。

Sample Input

3 10
Dobkeradops
7 5 23 10
PataPata
1 1 2 1
dop
5 3 11 14
2 300
Bydo System Alpha
7 11 4 7
Green Inferno
300 300 300 300

Output for Sample Input

29
462


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

class Main{
    public static void main(String[] args){
	BufferedReader sc=new BufferedReader(new InputStreamReader(System.in));
	try{
	    int N;
	    while((N = Integer.valueOf(sc.readLine()))!=0){
		char[] message = sc.readLine().toCharArray();
		int[] a, b;
		a = new int[N];
		b = new int[N];
		for(int i=0; i<N; i++){
		    String[] sp = sc.readLine().split(" ");
		    a[i] = Integer.valueOf(sp[0]);
		    b[i] = Integer.valueOf(sp[1]);
		}
		for(int i=N-1; i>=0; i--){
		    int sabun = b[i]-a[i];
		    char t;
		    message[a[i]-1] += sabun;
		    if(message[a[i]-1] > 'z')
			message[a[i]-1] -= 26;
		    message[b[i]-1] += sabun;
		    if(message[b[i]-1] > 'z')
			message[b[i]-1] -= 26;
		    t = message[a[i]-1];
		    message[a[i]-1] = message[b[i]-1];
		    message[b[i]-1] = t;
		}
		StringBuilder bb = new StringBuilder();
		for(int i=0; i<message.length; i++)
		    bb.append(message[i]);
		System.out.println(bb.toString());
	    }
	}catch (Exception e){
	    System.out.println("Error");
	}
    }
}

Problem A: スワップ暗号

R大学のとある2D好きな彼は、人に見られると赤面するような恥ずかしい文章を日頃からよく書いている。
そのため、第三者に自分の書いている文章を見られないために、彼が独自に考え出したスワップ暗号という手法により文章を暗号化している。
スワップ暗号では、次のようなステップをN回繰り返し、暗号化を行う。

文字列のai番目とbi番目を入れ替える

この2つの文字を、aiとbiの差分だけアルファベット順に戻す

ただし、アルファベット順で、'a'の前は'z'とする。

例えば、"aojwo"という文字列に対し、a1=1、b1=4、という暗号化操作を行ったとすると、次のようになる。

1番目と4番目を入れ替える("aojwo"→"wojao")

この2つの文字'w'と'a'を、1と4の差分＝3だけアルファベット順に戻す("wojao"→"tojxo")

'w'は、アルファベット順に3戻すと、'w'→'v'→'u'→'t'となる

'a'は、アルファベット順に3戻すと、'a'→'z'→'y'→'x'となる

よって、"aojwo"は、"tojxo"と暗号化される。

この暗号化により彼の文章は、原文がわからないように暗号化できるはずだったのだが、あろうことか彼は暗号化に使用したスワップ操作の過程を流出させてしまった。
あなたの仕事は、暗号化された文字列と暗号化に使用したスワップ操作が与えられたとき"復号"を行うプログラムを作成し、2D好きな彼をはずかしめてやることである。

Input

入力は、複数のデータセットからなる。データセットの総数は20以下である。
各データセットは、次の形式をしている。

N
message
a1 b1
...
ai bi
...
aN bN

N(0 < N ≤ 100)は、暗号化するときにスワップ操作した回数を示す整数である。
messageは、暗号化されたデータを示す。
暗号データは、アルファベットの小文字のみで構成される文字列である。
messageの長さをlenとしたとき、2 ≤ len ≤ 100と仮定してよい。

ai、biは、暗号化においてスワップを行った2つのインデックスを表している。
1 ≤ ai < bi ≤ lenと仮定してよい。
暗号化は、入力された順番にスワップ操作をしたものとする。

入力の終了は、0のみからなる1行で示される。このデータについては、処理する必要はない。

Output

各データセットに対して、復号した文字列を1行に出力せよ。

Sample Input

1
tojxo
1 4
5
uhcqmlmkv
4 5
6 9
3 6
1 7
3 6
5
shzxadexonr
8 9
3 9
5 8
4 9
10 11
0

Output for Sample Input

aojwo
shinryaku
shitadegeso


import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Main {

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

		String input = sc.next();

		boolean flag = input.length() >= 6 && input.matches(".*[a-z]+.*") && input.matches(".*[A-Z]+.*") && input.matches(".*[0-9]+.*");

		System.out.println(flag ? "VALID" : "INVALID");
	}

}

Problem A: Register Phase

インターネットをより安全に活用するために、堅牢なパスワードを使うことは重要である。それと同時に、同じパスワードを使い回さないことも非常に重要である。どんなに強いパスワードを使っていても、一箇所で平文が流出してしまえば、破るのは非常に容易になってしまう。もちろん、全てのアプリケーションがパスワードをハッシュ化し、SALTを適切に使用していれば流出してもそのような被害は発生しないが、いまだにパスワードを平文で保存しているアプリケーションはあるのである。

さて、そろそろコンテストが始まる。チームのアカウントを登録しなくては…。

問題

パスワードを表す文字列が与えられる。その文字列が以下の条件を全て満たすか調べ、満たす場合は"VALID"と、ひとつでも満たさない項目がある場合は"INVALID"と出力せよ。

文字列長が6以上である

数字を一つ以上含んでいる

大文字英字を一つ以上含んでいる

小文字英字を一つ以上含んでいる

入力

パスワードを表す文字列が一行に与えられる。

出力

パスワードを表す文字列が問題の条件を全て満たすなら"VALID"と、満たさない条件があるなら"INVALID"と、一行に出力せよ。

制約

パスワードを表す文字列は1文字以上20文字以内である

パスワードを表す文字列は英大文字、英小文字、数字のみを含む

入出力例

入力1

password

出力1

INVALID

世界中で広く使われているパスワードである。

入力2

AizuCamp2013

出力2

VALID

素晴しいパスワードである。

入力3

1234

出力3

INVALID

暗証番号として広く使われている。

入力4

NaBiO3

出力4

VALID

ぎりぎり6文字以上である。


import java.util.Scanner;

public class Main {
	static final int Big_Num = 1000000000;
	static long mul(int n,int h) {
		int ans = n;
		if(h==0)
			return 1;
		if(h==1)
			return ans;
		for(int i=0;i<h-1;i++) {
			ans *= n;
		}
		return ans;
	}

	static long f(String str,int n) {

		int[] an = new int[str.length()];
		int k = 0;
		for(int i=0;i<str.length();i++) {
			char s = str.charAt(i);
			if(Character.isDigit(s)) {
				an[k] = Integer.parseInt(String.valueOf(s));
				k++;
			}
		}

		long ans = 0;
		int kk = 0;
		for(int aa:an) {
			ans += mul(n,aa);
			kk++;
			if(kk==k)break;
		}
		return ans;
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);

			int n = sc.nextInt();
			int t = sc.nextInt();
			String str = sc.next();

			long ans = f(str,n);
			if(ans*t <= Big_Num && ans > 0)
				System.out.println(ans*t);
			else
				System.out.println("TLE");
	}
}

MathJax.Hub.Config({
tex2jax: { inlineMath: [['\\(','\\)']] }
});

Problem B: Time Complexity

ICPC World Finals 1日目

プログラミングコンテストではプログラムの実行時間を把握する事が重要だ。
実行時間の見積もりを誤り、 時間制限をオーバーしてしまうコードを書いてしまうと、 そのぶん時間をロスしてしまう。
ICPCのようにコンピュータが1台しか使えないチーム戦ではなおさらである。

そこで、ICPC World
Finalsを前に控えたティー氏はプログラムの実行時間を暗算で求める訓練を始めることにした。
「logは定数のようなもの」なので、まずは多項式に取り組むとしよう。

問題

ある問題の答えを計算するプログラムと、それを実行するコンピュータがある。
問題の入力を表す正整数\(n\)、 入力\(n\)に応じてプログラム中で実行される命令の数を表す多項式\(f(n)\)、
コンピュータの1命令の実行時間\(T\)[ナノ秒]（=\( 10^{-9} \)[秒]）が与えられる。
多項式\(f(n)\)の回数だけ命令を実行した時のプログラムの総実行時間が1秒「以下」であるかを判定し、
1秒「以下」であるならば総実行時間を求めよ。

入力

n T
f(n)

1行目に 問題の入力を表す正整数\(n\)と 1命令の実行時間[ナノ秒]を表す整数\(T\)が空白区切りで与えられる。
2行目に実行される命令の数を表す多項式\(f(n)\)が与えられる。

多項式\( f(n) \)は以下のBNFで表される。

<poly> ::= <poly> "+" <mono> | <mono>
<mono> ::= "n^" <num>
<num> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"

ここで各単項式n^kは、\(n\)の\(k\)乗を表す。

出力

プログラムの総実行時間が1秒「以下」である場合には総実行時間を[ナノ秒]単位で、1秒を「超過」する場合には"TLE"を1行に出力せよ。

制約

\( 1 \leq n \leq 10^{9}(= 1000000000) \)

\( 1 \leq T \leq 10^{9}(= 1000000000) \)

多項式\( f(n) \)の次数は0以上9以下、単項式の数は1以上10以下

入出力例

入力1

100 100
n^1+n^2+n^3

出力1

101010000

総実行時間は\( (100^{1} + 100^{2} + 100^{3}) \times 100 \)[ナノ秒]である。

入力2

1000 1
n^3+n^0

出力2

TLE

総実行時間は\( 1000^{3} + 1000^{0} = 10^{9}+1 \)[ナノ秒]であり、1[秒]を超えてしまう。

入力3

100000000 100000000
n^3

出力3

TLE

総実行時間は\( (10^{8})^{3} \times 10^{8} = 10^{32} \)[ナノ秒]である。


import java.util.Scanner;

public class Main {

	static Scanner sc = new Scanner(System.in);
	static String[] str;
	static int N;
	static boolean[][] g;

	public static void main(String[] args) throws Exception {
		while (true) {
			N = sc.nextInt();
			if (N == 0) break;
			str = new String[N];
			for (int i = 0; i < N; ++i) {
				str[i] = sc.next();
			}
			System.out.println(solve() ? "yes" : "no");
		}
	}

	static boolean solve() {
		g = new boolean[26][26];
		if (!construct(0, N, 0)) {
			return false;
		}
		for (int i = 0; i < 26; ++i) {
			boolean[] visited = new boolean[26];
			if (!dfs(i, visited)) {
				return false;
			}
		}
		return true;
	}

	static boolean dfs(int pos, boolean[] visited) {
		if (visited[pos]) return false;
		visited[pos] = true;
		for (int i = 0; i < 26; ++i) {
			if (g[pos][i]) {
				if (!dfs(i, visited)) {
					return false;
				}
			}
		}
		visited[pos] = false;
		return true;
	}

	static boolean construct(int s, int e, int pos) {
		// System.out.println(s + " " + e + " " + pos);
		if (e - s == 1) return true;
		while (s < e && str[s].length() == pos) {
			++s;
		}
		if (s >= e - 1) return true;
		int prev = s;
		for (int i = s + 1;; ++i) {
			if (i == e) {
				if (!construct(prev, i, pos + 1)) {
					return false;
				}
				break;
			}
			if (str[i].length() == pos) {
				return false;
			}
			if (str[i].charAt(pos) != str[prev].charAt(pos)) {
				g[str[prev].charAt(pos) - 'a'][str[i].charAt(pos) - 'a'] = true;
				// System.out.println(s + " " + e + " " + pos + " " + str[prev].charAt(pos) + " " + str[i].charAt(pos));
				if (!construct(prev, i, pos + 1)) {
					return false;
				}
				prev = i;
			}
		}
		return true;
	}

}

Problem Statement

We found a dictionary of the Ancient Civilization Mayo (ACM) during excavation of the ruins.
After analysis of the dictionary, we revealed they used a language that had not more than 26 letters.
So one of us mapped each letter to a different English alphabet and typed all the words in the dictionary into a computer.

How the words are ordered in the dictionary, especially whether they are ordered lexicographically, is an interesting topic to many people.
As a good programmer, you are requested to write a program to judge whether we can consider the words to be sorted in a lexicographical order.

Note:
In a lexicographical order, a word always precedes other words it is a prefix of.
For example, ab
precedes abc,
abde, and so on.

Input

The input consists of multiple datasets. Each dataset is formatted as follows:

n
string_1
...
string_n

Each dataset consists of n+1 lines.
The first line of each dataset contains an integer that indicates n (1 \leq n \leq 500).
The i-th line of the following n lines contains string_i, which consists of up to 10 English lowercase letters.

The end of the input is 0, and this should not be processed.

Output

Print either yes or
no in a line for each dataset, in the order of the input.
If all words in the dataset can be considered to be ordered lexicographically, print yes.
Otherwise, print no.

Sample Input

4
cba
cab
b
a
3
bca
ab
a
5
abc
acb
b
c
c
5
abc
acb
c
b
b
0

Output for the Sample Input

yes
no
yes
no


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

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 && !line.isEmpty()) {
			if (line.equals(".")) break;

			Deque<Character> rev = new ArrayDeque<Character>();
			Deque<Character> out = new ArrayDeque<Character>();
			int shift = 0;

			for (char c : line.toCharArray()) {
				switch (c) {
					case '[':
						out.offer(c);
						break;
					case ']':
						char d = out.removeLast();
						while (d != '[') {
							rev.push(d);
							d = out.removeLast();
						}
						// reverse
						while (!rev.isEmpty()) {
							out.offer(rev.removeLast());
						}
						break;
					case '+':
						shift++;
						break;
					case '-':
						shift--;
						break;
					case '?':
						out.offer('A');
						shift = 0;
						break;
					default:
						if (shift != 0) {
							shift %= 26;
							c += shift;
							if (c < 'A') {
								c += 26;
							} else if (c > 'Z') {
								c -= 26;
							}
							out.offer((char) c);
							shift = 0;
						} else {
							out.offer(c);
						}
						break;
				}
			}
			StringBuilder sb = new StringBuilder();
			while (!out.isEmpty()) {
				sb.append(out.poll());
			}
			System.out.println(sb.toString());
		}
	} //end while
} //end main

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

壊れた暗号生成器

JAG (Japanese Alumni Group) は多くのプログラマで構成される謎の組織であり，この組織の本部がある建物に入るためには毎回ある機械によって生成される暗号文を解かなくてはならない．
この暗号文は，'+'，'-'，'['，']' の記号と大文字のアルファベットからなっており，以下の BNF で定義される <Cipher> によって表される．

<Cipher> ::= <String> | <Cipher><String>
<String> ::= <Letter> | '['<Cipher>']'
<Letter> ::= '+'<Letter> | '-'<Letter> |
'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' |
'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z'

ここでそれぞれの記号は以下のような意味を表す．

+(文字) : その文字の次のアルファベットを表す (ただし 'Z' の次のアルファベットは 'A' であるとする)

-(文字) : その文字の前のアルファベットを表す (ただし 'A' の前のアルファベットは 'Z' であるとする)

[(文字列)] : その文字列を左右反転した文字列を表す

しかしこの暗号文を生成する機械には現在故障が発生しており，暗号文のうちアルファベットの箇所が数文字壊れて読めなくなっている場合がある．読めない文字は仮に '?' と表されている．
調査の結果，壊れた文字の埋め方は，復号後の文字列が，復号後の文字列としてありえる文字列の中で辞書順最小になるようなものであることがわかった．
あなたの仕事はこの暗号文を正しく復号することである．

Input

入力は複数のデータセットから構成される．
各データセットは，上記の BNF で定義された暗号文において，一部の大文字のアルファベットが ‘?’ に置き換えられた文字列を含む 1 行からなる．
各文字列の長さは $80$ 以下であると仮定してよい．
また各データセットに含まれる '?' の数は $0$ 以上 $3$ 以下であると仮定してよい．

入力の終了は '.' の1文字だけを含む行で表される．

Output

各データセットに対して，復号後の文字列が辞書順最小になるように暗号文を復号したときの，復号後の文字列を出力せよ．

Sample Input

A+A++A
Z-Z--Z+-Z
[ESREVER]
J---?---J
++++++++A+++Z-----------A+++Z
[[++-+--?[--++-?++-+++L]][-+-----+-O]]++++---+L
.

Output for Sample Input

ABC
ZYXZ
REVERSE
JAG
ICPC
JAPAN


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

public class Main {

	/**
	 * @param args
	 * @throws IOException
	 * @throws NumberFormatException
	 */
	public static void main(String[] args) throws NumberFormatException, IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		int n = Integer.parseInt(br.readLine());
		Stack<Integer> stack = new Stack<Integer>();
		int regularAns = 0;
		for(int i = 0; i < n; i++){
			String input = br.readLine();
			if(input.equals("A")){
				stack.push(1);
			}
			else if(!stack.isEmpty() && input.equals("Un")){
				stack.pop();
				regularAns++;
			}
		}

		if(stack.isEmpty() && regularAns > 0){
			System.out.println("YES");
		}
		else{
			System.out.println("NO");
		}
	}

}

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

A - 阿吽の呼吸

Problem Statement

時は進んで 2060 年，共に 70 歳を迎える前田さんと後藤さんは長い付き合いの友人であり，大学時代にACM-ICPCで共に戦った仲間でもある．

二人は今でもよく一緒にお茶を飲みつつ，競技プログラミングの話で盛り上がっている．

二人で一緒にお茶を飲む時，前田さんが 1 回Aと言うと，その発言の後に後藤さんがちょうど 1 回Unと返事をする習慣がいつのまにか出来た．

しかし最近後藤さんは物忘れや勘違いをすることが多く，前田さんがAと言っても，後藤さんはたまにUnの返事を忘れたり，余計に返事をしたりする．

ついこの間も前田さんと後藤さんはお茶を飲みながら，二人のお気に入りのデータ構造について話し込んでいたようだ．

この時の会話の中から，Aで表される前田さんの発言と，Unで表される後藤さんの返事のみからなる記録が時系列で与えられたとき，後藤さんが習慣通りに反応したとみなすことが出来るかチェックしてほしい．

注意点として，前田さんの発言に対し，後藤さんの返事が多少遅れても，後藤さんは習慣通りに反応したとみなせる場合がある，ということが挙げられる．
例えば，前田さんが2回連続してAと言った後，後藤さんが 2 回連続してUnと返事をして会話が終了した場合は，後藤さんが習慣通りの返事をしたとみなされる (Sample Input 2 参照)．

また，会話が終了した時点で，前田さんがAと言った回数と，後藤さんがUnと返事した回数が一致しても，後藤さんが習慣通りに返事をしたとはみなされない場合もあるので注意すること．
例えば，前田さんが1回Aと言った後，後藤さんが 2 回連続してUnと返事し，その後で前田さんが 1 回Aと言って会話が終了した場合は，後藤さんが習慣通りの返事をしたとはみなされない (Sample Input 3 参照)．

Input

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

$N$

$S_1$

$S_2$

$…$

$S_N$

最初の行はひとつの整数からなる．
$N$ は，記録に含まれる前田さんがAと発言した回数と後藤さんがUnと返事した回数の合計を表し，$1 \leq N \leq 100$ を満たす．
その後 $N$ 行に，文字列 $S_i$ が続き，各 $S_i (1 \leq i \leq N)$ はAかUnのどちらかに一致する．ここでAは前田さんの発言，Unは後藤さんの返事を表す．
$i$ の小さい順に $S_i$ が記録されたものとする．
前田さんと後藤さんが同時に発言することは無かったとする．

Output

後藤さんが習慣通りに反応したとみなすことが出来ればYES，出来なければNOを1行で出力すること．

Sample Input 1

4
A
Un
A
Un

Output for the Sample Input 1

YES

Sample Input 2

4
A
A
Un
Un

Output for the Sample Input 2

YES

Sample Input 3

4
A
Un
Un
A

Output for the Sample Input 3

NO

Sample Input 4

1
Un

Output for the Sample Input 4

NO


import java.util.*;
public class Main {

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

		while(true) {
			String str=in.next();
			if(str.charAt(0)=='#')break;
			int y=in.nextInt(),m=in.nextInt(),d=in.nextInt();

			if(y>31 || (y>=31 && m>=5)) {
				str="?";y-=30;
			}
			System.out.println(str+" "+y+" "+m+" "+d);
		}
	}

}

改元

平成31年4月30日をもって現行の元号である平成が終了し，その翌日より新しい元号が始まることになった．平成最後の日の翌日は新元号元年5月1日になる．

ACM-ICPC OB/OGの会 (Japanese Alumni Group; JAG) が開発するシステムでは，日付が和暦（元号とそれに続く年数によって年を表現する日本の暦）を用いて "平成 y 年 m 月 d 日" という形式でデータベースに保存されている．この保存形式は変更することができないため，JAGは元号が変更されないと仮定して和暦で表した日付をデータベースに保存し，出力の際に日付を正しい元号を用いた形式に変換することにした．

あなたの仕事はJAGのデータベースに保存されている日付を，平成または新元号を用いた日付に変換するプログラムを書くことである．新元号はまだ発表されていないため，"?" を用いて表すことにする．

Input

入力は複数のデータセットからなる．各データセットは次の形式で表される．

g y m d

g は元号を表す文字列であり， g=HEISEI が成り立つ．y, m, d は整数であり，それぞれ年，月，日を表す．1 ≤ y ≤ 100, 1 ≤ m ≤ 12, 1 ≤ d ≤ 31 が成り立つ．

2月30日などの和暦に存在しない日付はデータセットとして与えられない．和暦として正しく変換したときに，平成よりも前の元号を用いる必要がある日付もデータセットとして与えられない．

入力の終わりは '#' 一つのみからなる行であらわされる．データセットの個数は 100 個を超えない．

Output

各データセットについて，変換後の元号，年，月，日を空白で区切って 1 行に出力せよ．変換後の元号が "平成" である場合は "HEISEI" を元号として用い，新元号であれば "?" を用いよ．

通常，元号の第 1 年目は元年と表記するが，本問題の出力ではこの規則を無視し，1 を年として出力せよ．

Sample Input

HEISEI 1 1 8
HEISEI 31 4 30
HEISEI 31 5 1
HEISEI 99 12 31
HEISEI 38 8 30
HEISEI 98 2 22
HEISEI 2 3 26
HEISEI 28 4 23
#

Output for the Sample Input

HEISEI 1 1 8
HEISEI 31 4 30
? 1 5 1
? 69 12 31
? 8 8 30
? 68 2 22
HEISEI 2 3 26
HEISEI 28 4 23


import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String target = "E869120";
        int count = 0;
        for (int i = 0; i < n; i++) {
            if (target.equals(sc.next())) {
                count++;
            }
        }
        System.out.println(count);
    }
}

増えるE869120君 (Ninja E869120)

E869120君は分身が得意です。

ここに、$N$ 人のパ研部員がいます。しかし、このうちの何人かが E869120 君かもしれません。

そこで、あなたは $N$ 人全てのパ研部員に名前を聞きました。その結果、$N$ 人の部員はそれぞれ $S_1, S_2, S_3, \dots, S_N$ と名乗りました。

E869120 君は何人に分身していたでしょうか？ただし、全てのパ研部員は正直に自分の名前を答えるものとします。

入力

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

$N$
$S_1$
$S_2$
$S_3$
$\ldots$
$S_N$

出力

E869120君が何人に分身していたか、その人数を出力してください。ただし、E869120君がいない場合は「0」と出力してください。

ただし、最後には改行を入れること。

制約

$1 \leq N \leq 1000$

$1 \leq (S_i$ の長さ$) \leq 100$

$N$ は整数である。

$S_i$ は数字とアルファベット大文字からなる文字列である。

入力例1

5
E869120
TMJN
E869120
TAISA
YNYMXIAOLONGBAO

出力例1

2

E869120君は 2 人に分身しています。

入力例2

3
SQUARE1001
MENCOTTON
B2563125

出力例2

0

E869120君がいないときは0を出力してください。

入力例3

6
E8691200
E869121
E869122
E869123
E869124
E869125

出力例3

0

偽者に注意してください。


import java.util.Arrays;
import java.util.Scanner;
public class Main {

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);

		int n = sc.nextInt();

		int[] dp = new int[n+1];

		Arrays.fill(dp, -1);

		/*メモ化!!!
		int ans = fib(n,dp);

		System.out.println(ans);
		 */

		dp[0] = 1;

		dp[1] = 1;

		for(int i=2;i<=n;i++) {

			dp[i] = dp[i-1] + dp[i-2];
		}

		System.out.println(dp[n]);
	}

	/*メモ化!!!
	static int fib(int n, int[] dp) {

		if(n==0 || n==1) {

			dp[n] = 1;

			return dp[n];

		}else if(dp[n] != -1){

			return dp[n];
		}

		return fib(n-1,dp) + fib(n-2,dp);

	}*/

}

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

Fibonacci Number

Write a program which prints $n$-th fibonacci number for a given integer $n$. The $n$-th fibonacci number is defined by the following recursive formula:

\begin{equation*}
fib(n)= \left \{
\begin{array}{ll}
1　 & (n = 0) \\
1　 & (n = 1) \\
fib(n - 1) + fib(n - 2) & \\
\end{array}
\right.
\end{equation*}

Input

An integer $n$ is given.

output

Print the $n$-th fibonacci number in a line.

Constraints

$0 \leq n \leq 44$

Sample Input 1

3

Sample Output 1

3


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;
import java.util.InputMismatchException;

public class Main {

	private static int[][] cache;
	private static int[] r;
	private static int[] c;

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

		int n = sc.nextInt();
		r = new int[n];
		c = new int[n];

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

		// ボトムアップ型１、メモリ節約
		cache = new int[n][];
		for (int i = 0; i < n; i++) {
			cache[i] = new int[n - i];
			Arrays.fill(cache[i], Integer.MAX_VALUE);
			cache[i][i - i] = 0;  // cache[行][列 - 行]
		}

		for (int l = 1; l < n; l++) {
			for (int i = 0; i + l < n && i < n; i++) {
				int j = i + l;
				for (int k = 0; k < l; k++) {
					cache[i][j - i] = Math.min(cache[i][j - i], cache[i][i + k - i] + r[i] * r[i+k+1] * c[j] + cache[i + k + 1][j - (i + k + 1)]);
				}
			}
		}
		int ret = cache[0][n -1 - 0];

		System.out.println(ret);

		sc.close();
	}

	@SuppressWarnings("unused")
	private static class Scanner {
		InputStreamReader isr;
		BufferedReader br;
		StreamTokenizer st;

		private Scanner() {
		}

		Scanner (InputStream in) {
			isr = new InputStreamReader(in);
			br = new BufferedReader(isr);
			st = new StreamTokenizer(br);
		}

		String next() throws RuntimeException  {
			try {
				if (st.nextToken() != StreamTokenizer.TT_WORD) {
				}
			} catch (IOException e) {
				throw new IllegalStateException();
			}

			return st.sval;
		}

		int nextInt() throws RuntimeException {
			try {
				if (st.nextToken() != StreamTokenizer.TT_NUMBER) {
					throw new InputMismatchException();
				}
			} catch (IOException e) {
				throw new IllegalStateException();
			}

			return (int)st.nval;
		}

		void close() {
		}
	}
}

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

Matrix-chain Multiplication

The goal of the matrix-chain multiplication problem is to find the most efficient way to multiply given $n$ matrices $M_1, M_2, M_3,...,M_n$.

Write a program which reads dimensions of $M_i$, and finds the minimum number of scalar multiplications to compute the maxrix-chain multiplication $M_1M_2...M_n$.

Input

In the first line, an integer $n$ is given. In the following $n$ lines, the dimension of matrix $M_i$ ($i = 1...n$) is given by two integers $r$ and $c$ which respectively represents the number of rows and columns of $M_i$.

Output

Print the minimum number of scalar multiplication in a line.

Constraints

$1 \leq n \leq 100$

$1 \leq r, c \leq 100$

Sample Input 1

6
30 35
35 15
15 5
5 10
10 20
20 25

Sample Output 1

15125


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

public class Main {
	ArrayList<Vertex> nodes = new ArrayList<>();
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		String[] holder = in.nextLine().split(" ");
		int n = Integer.parseInt(holder[0]);
		int m = Integer.parseInt(holder[1]);
		Main graph = new Main();
		for (int i = 0; i < n; i++) {
			Vertex v = new Vertex(i);
			graph.addVertex(v);
		}
		for (int i = m; i > 0; i--) {
			String[] relation = in.nextLine().split(" ");
			int s = Integer.parseInt(relation[0]);
			int t = Integer.parseInt(relation[1]);
			Vertex sv = graph.getVertex(s);
			Vertex tv = graph.getVertex(t);
			sv.addNeighbor(tv);
			tv.addNeighbor(sv);
		}

		int q = Integer.parseInt(in.nextLine());
		for (int i = q; i > 0; i--) {
			String[] query = in.nextLine().split(" ");
			int s = Integer.parseInt(query[0]);
			int t = Integer.parseInt(query[1]);
			Vertex start = graph.getVertex(s);
			Vertex end = graph.getVertex(t);
			LinkedList<Vertex> fringe = new LinkedList<>();
			ArrayList<Vertex> searched = new ArrayList<>();
			fringe.add(start);
			boolean found = graph.BFS(start, end, fringe, searched);
			if (found) {
				System.out.println("yes");
			}
			else {
				System.out.println("no");
			}
		}

	}

	public void addVertex(Vertex v) {
		nodes.add(v);
	}

	public Vertex getVertex(int index) {
		return nodes.get(index);
	}

	// Performs DFS from a specified starting node and returns true if the end can be reached from it
	// False otherwise
	public boolean BFS(Vertex start, Vertex end, LinkedList<Vertex> fringe, ArrayList<Vertex> searched) {
		if (fringe.isEmpty()) {
			return false;
		}
		else if (start.equals(end)) {
			return true;
		}
		else {

			Vertex pull = fringe.poll();
			searched.add(pull);
			for (Vertex neigh : pull.neighbors) {
				if (neigh.equals(end)) {
					return true;
				} else if (searched.contains(neigh)) {

				}
				else {
					fringe.add(neigh);
				}
			}
			return BFS(pull, end, fringe, searched);
		}
	}

}

class Vertex {
	public ArrayList<Vertex> neighbors = new ArrayList<>();
	public int value;
	public boolean disc;

	public Vertex(int val) {
		value = val;
		disc = false;
	}

	public void addNeighbor (Vertex n) {
		neighbors.add(n);
	}

	public String toString() {
		return "" + this.value + " ";
	}

	public boolean equals(Vertex v) {
		if (this.value == v.value) {
			return true;
		}
		else {
			return false;
		}
	}
}

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

Connected Components

Write a program which reads relations in a SNS (Social Network Service), and judges that given pairs of users are reachable each other through the network.

Input

In the first line, two integer $n$ and $m$ are given. $n$ is the number of users in the SNS and $m$ is the number of relations in the SNS. The users in the SNS are identified by IDs $0, 1, ..., n-1$.

In the following $m$ lines, the relations are given. Each relation is given by two integers $s$ and $t$ that represents $s$ and $t$ are friends (and reachable each other).

In the next line, the number of queries $q$ is given. In the following $q$ lines, $q$ queries are given respectively. Each query consists of two integers $s$ and $t$ separated by a space character.

Output

For each query, print "yes" if $t$ is reachable from $s$ through the social network, "no" otherwise.

Constraints

$2 \leq n \leq 100,000$

$0 \leq m \leq 100,000$

$1 \leq q \leq 10,000$

Sample Input

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

Sample Output

yes
yes
no


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

public class Main {

	private static Scanner sc;
	private static Printer pr;

	private static void solve() {
		char[] t = sc.next().toCharArray();
		SuffixArray sa = new SuffixArray(t);

		int q = sc.nextInt();
		for (int i = 0; i < q; i++) {
			String p = sc.next();

			if (sa.contains(p.toCharArray())) {
				pr.println("1");
			} else {
				pr.println("0");
			}
		}
	}

	private static class SuffixArray {
		char[] s;
		int n;

		Integer[] sa;
		int[] rank;
		int[] rtmp;
		SaComparator sac;

		int k;

		SuffixArray(char[] str) {
			this.s = str;
			n = s.length;

			sa = new Integer[n + 1];
			rank = new int[n + 1];
			rtmp = new int[n + 1];
			for (int i = 0; i <= n; i++) {
				sa[i] = i;
				if (i < n) {
					rank[i] = s[i];
				} else {
					rank[i] = 0;
				}
			}

			sac = new SaComparator();

			for (k = 1; k < n; k *= 2) {
				Arrays.sort(sa, sac);

				rtmp[sa[0]] = rank[sa[0]];
				for (int i = 1; i <= n; i++) {
					if (sac.compare(sa[i - 1], sa[i]) == 0) {
						rtmp[sa[i]] = rtmp[sa[i - 1]];
					} else {
						rtmp[sa[i]] = rtmp[sa[i - 1]] + 1;
					}
				}

				int[] tmp = rtmp;
				rtmp = rank;
				rank = tmp;
			}
		}

		boolean contains(char[] t) {
			int l = 0;
			int r = n;
			while (r > l) {
				int mid = l + (r - l) / 2;
				int res = compare(s, mid, t);

				if (res >= 0) {
					r = mid;
				} else {
					l = mid + 1;
				}
			}

			return compare(s, l, t) == 0;
		}

		int compare(char[] s, int mid, char[] t) {
			int m = t.length;

			for (int i = 0; sa[mid] + i < n && i < m; i++) {
				int res = s[sa[mid] + i] - t[i];

				if (res != 0) {
					return res;
				}
			}

			if (sa[mid] + m < m) {
				return -1;
			} else {
				return 0;
			}
		}

		private class SaComparator implements Comparator<Integer> {

			@Override
			public int compare(Integer i, Integer j) {
				if (rank[i] != rank[j]) {
					return Integer.compare(rank[i], rank[j]);
				}

				int ri = i + k <= n ? rank[i + k] : -1;
				int rj = j + k <= n ? rank[j + k] : -1;
				return Integer.compare(ri, rj);
			}

		}
	}

	// ---------------------------------------------------
	public static void main(String[] args) {
		sc = new Scanner(System.in);
		pr = new Printer(System.out);

		solve();

		pr.close();
		sc.close();
	}

	@SuppressWarnings("unused")
	private static class Scanner {
		BufferedReader br;

		Scanner (InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
		}

		private boolean isPrintable(int ch) {
			return ch >= '!' && ch <= '~';
		}

		private boolean isCRLF(int ch) {
			return ch == '\n' || ch == '\r' || ch == -1;
		}

		private int nextPrintable() {
			try {
				int ch;
				while (!isPrintable(ch = br.read())) {
					if (ch == -1) {
						throw new NoSuchElementException();
					}
				}

				return ch;
			} catch (IOException e) {
				throw new NoSuchElementException();
			}
		}

		String next() {
			try {
				int ch = nextPrintable();
				StringBuilder sb = new StringBuilder();
				do {
					sb.appendCodePoint(ch);
				} while (isPrintable(ch = br.read()));

				return sb.toString();
			} catch (IOException e) {
				throw new NoSuchElementException();
			}
		}

		int nextInt() {
			try {
				// parseInt from Integer.parseInt()
				boolean negative = false;
				int res = 0;
				int limit = -Integer.MAX_VALUE;
				int radix = 10;

				int fc = nextPrintable();
				if (fc < '0') {
					if (fc == '-') {
						negative = true;
						limit = Integer.MIN_VALUE;
					} else if (fc != '+') {
						throw new NumberFormatException();
					}
					fc = br.read();
				}
				int multmin = limit / radix;

				int ch = fc;
				do {
					int digit = ch - '0';
					if (digit < 0 || digit >= radix) {
						throw new NumberFormatException();
					}
					if (res < multmin) {
						throw new NumberFormatException();
					}
					res *= radix;
					if (res < limit + digit) {
						throw new NumberFormatException();
					}
					res -= digit;

				} while (isPrintable(ch = br.read()));

				return negative ? res : -res;
			} catch (IOException e) {
				throw new NoSuchElementException();
			}
		}

		long nextLong() {
			try {
				// parseLong from Long.parseLong()
				boolean negative = false;
				long res = 0;
				long limit = -Long.MAX_VALUE;
				int radix = 10;

				int fc = nextPrintable();
				if (fc < '0') {
					if (fc == '-') {
						negative = true;
						limit = Long.MIN_VALUE;
					} else if (fc != '+') {
						throw new NumberFormatException();
					}
					fc = br.read();
				}
				long multmin = limit / radix;

				int ch = fc;
				do {
					int digit = ch - '0';
					if (digit < 0 || digit >= radix) {
						throw new NumberFormatException();
					}
					if (res < multmin) {
						throw new NumberFormatException();
					}
					res *= radix;
					if (res < limit + digit) {
						throw new NumberFormatException();
					}
					res -= digit;

				} while (isPrintable(ch = br.read()));

				return negative ? res : -res;
			} catch (IOException e) {
				throw new NoSuchElementException();
			}
		}

		float nextFloat() {
			return Float.parseFloat(next());
		}

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

		String nextLine() {
			try {
				int ch;
				while (isCRLF(ch = br.read())) {
					if (ch == -1) {
						throw new NoSuchElementException();
					}
				}
				StringBuilder sb = new StringBuilder();
				do {
					sb.appendCodePoint(ch);
				} while (!isCRLF(ch = br.read()));

				return sb.toString();
			} catch (IOException e) {
				throw new NoSuchElementException();
			}
		}

		void close() {
			try {
				br.close();
			} catch (IOException e) {
//				throw new NoSuchElementException();
			}
		}
	}

	private static class Printer extends PrintWriter {
		Printer(PrintStream out) {
			super(out);
		}
	}
}

String Search

Determine whether a text T includes a pattern P. Your program should answer for given queries consisting of P_i.

Input

In the first line, a text T is given. In the second line, an integer Q denoting the number of queries is given. In the following Q lines, the patterns P_i are given respectively.

Output

For each question, print 1 if the text includes P_i, or print 0 otherwise.

Constraints

1 ≤ length of T ≤ 1000000

1 ≤ length of P_i ≤ 1000

1 ≤ Q ≤ 10000

The input consists of alphabetical characters and digits

Sample Input 1

aabaaa
4
aa
ba
bb
xyz

Sample Output 1

1
1
0
0


import java.util.Scanner;

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

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

		for (int i = 1; i < N; i++) {
			StringBuilder sb = new StringBuilder();
			for (int k : A) {
				sb.append(k);
				sb.append(" ");
			}

			System.out.println(sb.toString().trim());
			int v = A[i];
			int j = i - 1;

			while (j >= 0 && A[j] > v) {
				A[j + 1] = A[j];
				j--;
			}
			A[j + 1] = v;
		}
		StringBuilder sb = new StringBuilder();
		for (int k : A) {
			sb.append(k);
			sb.append(" ");
		}

		System.out.println(sb.toString().trim());
	}
}

Insertion Sort

Write a program of the Insertion Sort algorithm which sorts a sequence A in ascending order. The algorithm should be based on the following pseudocode:

for i = 1 to A.length-1
key = A[i]
/* insert A[i] into the sorted sequence A[0,...,j-1] */
j = i - 1
while j >= 0 and A[j] > key
A[j+1] = A[j]
j--
A[j+1] = key

Note that, indices for array elements are based on 0-origin.

To illustrate the algorithms, your program should trace intermediate result for each step.

Input

The first line of the input includes an integer N, the number of elements in the sequence.

In the second line, N elements of the sequence are given separated by a single space.

Output

The output consists of N lines. Please output the intermediate sequence in a line for each step. Elements of the sequence should be separated by single space.

Constraints

1 ≤ N ≤ 100

Sample Input 1

6
5 2 4 6 1 3

Sample Output 1

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

Sample Input 2

3
1 2 3

Sample Output 2

1 2 3
1 2 3
1 2 3

Hint

Template in C


import java.util.Scanner;
public class Main {

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

		int n = in.nextInt();
		int[] input = new int[n];

		for(int i=0; i < n; i++){
			input[i] = in.nextInt();
		}

		for(int i=0; i < input.length; i++){
			System.out.print(input[i] + " ");
		}
		System.out.println();

		for(int i=1; i < input.length; i++){
			int key = input[i];
			int j = i-1;
			while(j >=0 && input[j] > key){
				input[j+1] = input[j];
				j--;
			}
			input[j+1] = key;
			for(int k=0; k < input.length; k++){
				System.out.print(input[k] + " ");
			}
			System.out.println();
		}
	}
}


import java.util.Scanner;
public class Main {
	public static void main(String[] arg){
		Scanner sc = new Scanner(System.in);
		int a = sc.nextInt();
		int b = sc.nextInt();
		if(a >= b){
			gcd(a,b);
		}else{
			gcd(b,a);
		}
	}

	static void gcd(int n,int m){
		if((n % m) == 0) {
			System.out.println(m);
		}else if(m == 1){
			System.out.println(1);
		}else{
			int m1 = (n % m);
			gcd(m,m1);
		}
	}
}

Greatest Common Divisor

Write a program which finds the greatest common divisor of two natural numbers a and b

Input

a and b are given in a line sparated by a single space.

Output

Output the greatest common divisor of a and b.

Constrants

1 ≤ a, b ≤ 109

Hint

You can use the following observation:

For integers x and y, if x ≥ y, then gcd(x, y) = gcd(y, x%y)

Sample Input 1

54 20

Sample Output 1

2

Sample Input 2

147 105

Sample Output 2

21


import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int cnt = 0;
		int[] num = new int[n];
		for(int i = 0; i < n; i ++){
			num[i] = sc.nextInt();
		}
		System.out.println(judge(num));
	}
	static int judge(int[] num){
		final int max = 1000000 + 1;
		int cnt = 0;
		boolean isp = false;
		for(int i = 0; i < num.length; i++){
			isp = true;
			if(num[i] == (2|3|5|7)) {
				cnt++; continue;
			}
			for(int j = 2; j < num[i]/2; j++){
				if(num[i] % j == 0) {
					isp = false; break;
				}
			}
			if(isp) cnt++;
		}
		return cnt;
	}
}

Prime Numbers

A prime number is a natural number which has exactly two distinct natural number divisors: 1 and itself. For example, the first four prime numbers are: 2, 3, 5 and 7.

Write a program which reads a list of N integers and prints the number of prime numbers in the list.

Input

The first line contains an integer N, the number of elements in the list.

N numbers are given in the following lines.

Output

Print the number of prime numbers in the given list.

Constraints

1 ≤ N ≤ 10000

2 ≤ an element of the list ≤ 108

Sample Input 1

5
2
3
4
5
6

Sample Output 1

3

Sample Input 2

11
7
8
9
10
11
12
13
14
15
16
17

Sample Output 2

4


import java.util.*;

public class Main {
	public static void main(String[] a) {
		Scanner input = new Scanner(System.in);
		int loop = input.nextInt();
		int max = -1;
		int[] num = new int[loop];

		if (loop >= 2 && loop <= 200000) {

			for (int i = 0; i < loop; i++) {
				int newNum = input.nextInt();

				if (newNum >= 1 && newNum <= 1000000000) {
					num[i] = newNum;
					if (i == 1)
						max = num[1] - num[0];

					if (i > 0) {

						for (int j = 0; j < i; j++) {
							max = newNum - num[j] >= max ? newNum - num[j]
									: max;
						}
					}
				}

			}

			System.out.println(max);

		}

	}

}

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

Maximum Profit

You can obtain profits from foreign exchange margin transactions. For example, if you buy 1000 dollar at a rate of 100 yen per dollar, and sell them at a rate of 108 yen per dollar, you can obtain (108 - 100) × 1000 = 8000 yen.

Write a program which reads values of a currency $R_t$ at a certain time $t$ ($t = 0, 1, 2, ... n-1$), and reports the maximum value of $R_j - R_i$ where $j > i$ .

Input

The first line contains an integer $n$. In the following $n$ lines, $R_t$ ($t = 0, 1, 2, ... n-1$) are given in order.

Output

Print the maximum value in a line.

Constraints

$2 \leq n \leq 200,000$

$1 \leq R_t \leq 10^9$

Sample Input 1

6
5
3
1
3
4
3

Sample Output 1

3

Sample Input 2

3
4
3
2

Sample Output 2

-1


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

public class Main {

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

    try(BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {

      int n = Integer.parseInt(br.readLine());
      int minv = Integer.parseInt(br.readLine());
      int n1   = Integer.parseInt(br.readLine());
      int maxv = n1- minv;
      if ( n1 < minv ) minv = n1;

      for( int i=2,r,mv; i<n; i++ ) {
        r = Integer.parseInt(br.readLine());
        if ( (mv = r-minv) > maxv ) maxv = mv;
        else if ( r < minv ) minv = r;
      }

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


import java.util.Scanner;

public class Main {
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		Integer i,j,max=0,n = sc.nextInt(),res = Integer.MIN_VALUE;
		int [] price = new int [n];

		for(i=0;i<n;i++){
			price[i] = sc.nextInt();
		}
		for(i=0;i<n-1;i++){
			max = 1;
			for(j=i+1;j<n;j++){
				if(max < price[j]) max = price[j];
			}
			res = Math.max(res, max-price[i]);
		}
		System.out.println(res);
	}

}


import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        int N;
        int num[];
        String line;

        Scanner scan=new Scanner(System.in);

        line=scan.next();
        N=Integer.parseInt(line);

        if(N<1||100<N){
            return;
        }

        num=new int[N];

        for(int i=0;i<N;i++){
            num[i]=Integer.parseInt(scan.next());
            if(num[i]<0||num[i]>100){
                return;
            }
        }

        //バブルソート
        int swap_num=0;
        for(int i=0;i<N-1;i++){
            for(int j=N-1;j>i;j--){
                if(num[j]<num[j-1]){
                    int temp=num[j];
                    num[j]=num[j-1];
                    num[j-1]=temp;

                    swap_num++;
                }
            }
        }

        for(int i=0;i<N;i++){
            System.out.print(num[i]+" ");
        }
        System.out.println();
        System.out.println(swap_num);
    }
}

Bubble Sort

Write a program of the Bubble Sort algorithm which sorts a sequence A in ascending order. The algorithm should be based on the following pseudocode:

BubbleSort(A)
1 for i = 0 to A.length-1
2 for j = A.length-1 downto i+1
3 if A[j] < A[j-1]
4 swap A[j] and A[j-1]

Note that, indices for array elements are based on 0-origin.

Your program should also print the number of swap operations defined in line 4 of the pseudocode.

Input

The first line of the input includes an integer N, the number of elements in the sequence.

In the second line, N elements of the sequence are given separated by spaces characters.

Output

The output consists of 2 lines.

In the first line, please print the sorted sequence. Two contiguous elements of the sequence should be separated by a space character.

In the second line, please print the number of swap operations.

Constraints

1 ≤ N ≤ 100

Sample Input 1

5
5 3 2 4 1

Sample Output 1

1 2 3 4 5
8

Sample Input 2

6
5 2 4 6 1 3

Sample Output 2

1 2 3 4 5 6
9


import java.util.*;

public class Main {

	int count = 0;

	void bubbleSort(int[] A) {
		boolean f = true;
		while (f) {
			f = false;
			for (int i = A.length - 1; i >= 1; i--) {
				if (A[i] < A[i-1]) {
					int tmp = A[i];
					A[i] = A[i-1];
					A[i-1] = tmp;
					f = true;
					count++;
				}
			}
		}
	}

	void run() {
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt();
		int[] A = new int[n];
		for (int i = 0; i < A.length; i++) {
			A[i] = scan.nextInt();
		}
		count = 0;
		bubbleSort(A);
		for (int i = 0; i < A.length; i++) {
			System.out.print(A[i] + " ");
		}
		System.out.println();
		System.out.println(count);
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new Main().run();
	}

}


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

class Main{
    public static void main(String[] args){
	int N;
	boolean stablejudge = true;
	InputStream inputStream = System.in;
	InputReader input = new InputReader(inputStream);
	N = input.nextInt();
	// String[] nums = new String[N];
	// String[] numSelectionString = new String[N];
	// String[] numBubbleString = new String[N];
	int[] nums = new int[N];
	// int[] numSelection = new int[N];
	for(int i = 0;i < N;i++){
	    nums[i] = input.nextInt();
	    // numBubbleString[i] = nums[i];
	    // numSelectionString[i] = nums[i];
	    // numBubble[i] = Integer.parseInt(nums[i].substring(1));
	    // numSelection[i] = Integer.parseInt(nums[i].substring(1));
	}
	selectionSort(N,nums);
    }
	// print(bubbleSort(N,numBubble,numBubbleString));
	// 	isStable(bubbleSort(N,numBubble,numBubbleString),bubbleSort(N,numBubble,numBubbleString));
	      // isStable(bubbleSort(N,numBubble,numBubbleString),selectionSort(N,numSelection,numSelectionString));

    //     public static String[] bubbleSort(int N,int[] numBubble,String[] numBubbleString){
    // 	for(int i = 0;i < N - 1;i++){
    // 	    for(int j = N - 1;j > i;j--){
    // 		if(numBubble[j - 1] > numBubble[j]){
    // 		    int tmp = numBubble[j - 1];
    // 		    numBubble[j - 1] = numBubble[j];
    // 		    numBubble[j] = tmp;

    // 		    String temp = numBubbleString[j - 1];
    // 		    numBubbleString[j - 1] = numBubbleString[j];
    // 		    numBubbleString[j] = temp;
    // 		}
    // 	    }
    // 	}
    // 	return numBubbleString;
    // }

	    public static void selectionSort(int N,int[] numSelection){
	    int count = 0;
	    for(int i = 0;i < N;i++){
		int minj = i;
		for(int j = i;j < N;j++){
		    //最小の要素を見つける
		    if(numSelection[j] < numSelection[minj]){
			//最小の要素の添字をminjに代入
			minj = j;

		    }
		}

		if(numSelection[i] != numSelection[minj]){
		    int tmp = numSelection[i];
		    numSelection[i] = numSelection[minj];
		    numSelection[minj] = tmp;

		    count++;
		    // String temp = numSelectionString[i];
		    // numSelectionString[i] = numSelectionString[minj];
		    // numSelectionString[minj] = temp;
		}
	    }
	    print(numSelection);
	    System.out.println(count);

	// return numSelectionString;
	}

	public static void print(int[] num){
	    String ans;
    	ans = Arrays.toString(num); //文字列に変換する
    	ans = ans.replaceAll(",", ""); //","を消去
    	ans = ans.replace("[", ""); // "["を消去
    	ans = ans.replace("]", ""); // "]"を消去
    	System.out.println(ans);
    }
    // static void print(String[] nums){
    // 	for (int i = 0; i < nums.length; i++) {
    //         if (i != 0) {
    //             System.out.print(" ");
    //         }
    //         System.out.print(nums[i]);
    //     }
    //     System.out.println();
    // }
        // static void isStable(String[] stable,String[] target){

	// if(Arrays.equals(stable,target)){
	//     System.out.println("Stable");
	// }else{
	//     System.out.println("Not stable");
	// }
}

class InputReader{
    StringTokenizer tokenizer;
    BufferedReader reader;
    //コンストラクタ
    public InputReader(InputStream stream){
	/*InputStreamReaderはバイトストリームから文字ストリームの橋渡しの役目を持ちこれ
	  が最高効率となる形になる*/
	reader = new BufferedReader(new InputStreamReader(stream),32768);
	tokenizer = null;
    }
    public String next(){
	while(tokenizer == null || !tokenizer.hasMoreTokens()){
	    try{
		tokenizer = new StringTokenizer(reader.readLine());
	    }catch(IOException e){
		throw new RuntimeException(e);
	    }
	}
	return tokenizer.nextToken();
    }
    public int nextInt(){

	return Integer.parseInt(next());
    }
}

Selection Sort

Write a program of the Selection Sort algorithm which sorts a sequence A in ascending order. The algorithm should be based on the following pseudocode:

SelectionSort(A)
1 for i = 0 to A.length-1
2 mini = i
3 for j = i to A.length-1
4 if A[j] < A[mini]
5 mini = j
6 swap A[i] and A[mini]

Note that, indices for array elements are based on 0-origin.

Your program should also print the number of swap operations defined in line 6 of the pseudocode in the case where i ≠ mini.

Input

The first line of the input includes an integer N, the number of elements in the sequence.

In the second line, N elements of the sequence are given separated by space characters.

Output

The output consists of 2 lines.

In the first line, please print the sorted sequence. Two contiguous elements of the sequence should be separated by a space character.

In the second line, please print the number of swap operations.

Constraints

1 ≤ N ≤ 100

Sample Input 1

6
5 6 4 2 1 3

Sample Output 1

1 2 3 4 5 6
4

Sample Input 2

6
5 2 4 6 1 3

Sample Output 2

1 2 3 4 5 6
3


import java.util.Scanner;

public class Main {
    public static void trace(int[] a,int n){
        for (int i = 0;i < n;i++){
            if(i > 0)
                System.out.print(" ");
            System.out.print(a[i]);
        }
        System.out.print("\n");
    }

    public static int selectionSort(int[] a,int n){
        int count = 0;
        for(int i = 0;i < n;i++){
            int minj = i;
            int j;
            for(j = i;j < n;j++){
                if(a[j] < a[minj]){
                    minj = j;
                }
            }
            int temp = a[i];
            a[i] = a[minj];
            a[minj] = temp;
            if(minj != i)
                count++;
        }
        return count;
    }

    public static void main(String[] args) {
        int n;
        int[] a = new int[100];
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        for (int i = 0; i < n; i++)
            a[i] = sc.nextInt();
        int count = selectionSort(a,n);
        trace(a, n);
        System.out.println(count);
    }
}


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

public class Main {
	private static FastScanner sc = new FastScanner();
	private static final int MAX_NUM = 9;

	public static void main(String[] args) {
		int N = sc.nextInt();

		Card[] C = new Card[N];
		Card[] C_before = new Card[N];
		for(int i=0; i<N; i++) {
			char[] temp = sc.next().toCharArray();
			C[i] = new Card(temp[0], Integer.parseInt("" + temp[1]));
			C_before[i] = new Card(temp[0], Integer.parseInt("" + temp[1]));
		}

		for(int i=0; i<N; i++) {
			for(int j=N-1; j>i; j--) {
				if(C[j].num < C[j-1].num){
					Card temp = C[j];
					C[j] = C[j-1];
					C[j-1] = temp;
				}
			}
		}

		for(int i=0; i<N; i++) {
			System.out.print("" + C[i].suit +  C[i].num);
			if(i != N-1) {
				System.out.print(" ");
			}
		}
		System.out.println();

		boolean flag = true;
		for(int i=1; i<=MAX_NUM; i++) {
			String order_suit = "";
			String order_suit_before = "";

			for(int j=0; j<N; j++ ){
				if(C[j].num == i) {
					order_suit += C[j].suit;
				}
				if(C_before[j].num == i) {
					order_suit_before += C_before[j].suit;
				}
			}

//			System.out.println(order_suit);
//			System.out.println(order_suit_before);

			if(!order_suit.equals(order_suit_before)) {
				flag = false;
				break;
			}
		}

		if(flag) {
			System.out.println("Stable");
		} else {
			System.out.println("Not Stable");
		}

		for(int i=0; i<N; i++) {
			C[i].suit = C_before[i].suit;
			C[i].num = C_before[i].num;
		}

		for(int i=0; i<N; i++){
			int idx_min = i;
			for(int j=i; j<N; j++){
				if(C[j].num < C[idx_min].num){
					idx_min = j;
				}
			}

			if(idx_min != i){
				Card temp = C[i];
				C[i] = C[idx_min];
				C[idx_min] = temp;
			}
		}

		for(int i=0; i<N; i++) {
			System.out.print("" + C[i].suit +  C[i].num);
			if(i != N-1) {
				System.out.print(" ");
			}
		}
		System.out.println();

		flag = true;
		for(int i=1; i<=MAX_NUM; i++) {
			String order_suit = "";
			String order_suit_before = "";

			for(int j=0; j<N; j++ ){
				if(C[j].num == i) {
					order_suit += C[j].suit;
				}
				if(C_before[j].num == i) {
					order_suit_before += C_before[j].suit;
				}
			}

//			System.out.println(order_suit);
//			System.out.println(order_suit_before);

			if(!order_suit.equals(order_suit_before)) {
				flag = false;
				break;
			}
		}

		if(flag) {
			System.out.println("Stable");
		} else {
			System.out.println("Not Stable");
		}
	}

	static class Card{
		char suit;
		int num;

		public Card(char suit, int num) {
			this.suit = suit;
			this.num = num;
		}
	}

	static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException  e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

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

        long nextLong() {
            return Long.parseLong(next());
        }

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

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
}

Stable Sort

Let's arrange a deck of cards. There are totally 36 cards of 4 suits(S, H, C, D) and 9 values (1, 2, ... 9). For example, 'eight of heart' is represented by H8 and 'one of diamonds' is represented by D1.

Your task is to write a program which sorts a given set of cards in ascending order by their values using the Bubble Sort algorithms and the Selection Sort algorithm respectively. These algorithms should be based on the following pseudocode:

BubbleSort(C)
1 for i = 0 to C.length-1
2 for j = C.length-1 downto i+1
3 if C[j].value < C[j-1].value
4 swap C[j] and C[j-1]

SelectionSort(C)
1 for i = 0 to C.length-1
2 mini = i
3 for j = i to C.length-1
4 if C[j].value < C[mini].value
5 mini = j
6 swap C[i] and C[mini]

Note that, indices for array elements are based on 0-origin.

For each algorithm, report the stability of the output for the given input (instance). Here, 'stability of the output' means that: cards with the same value appear in the output in the same order as they do in the input (instance).

Input

The first line contains an integer N, the number of cards.

N cards are given in the following line. Each card is represented by two characters. Two consecutive cards are separated by a space character.

Output

In the first line, print the arranged cards provided by the Bubble Sort algorithm. Two consecutive cards should be separated by a space character.

In the second line, print the stability ("Stable" or "Not stable") of this output.

In the third line, print the arranged cards provided by the Selection Sort algorithm. Two consecutive cards should be separated by a space character.

In the fourth line, print the stability ("Stable" or "Not stable") of this output.

Constraints

1 ≤ N ≤ 36

Sample Input 1

5
H4 C9 S4 D2 C3

Sample Output 1

D2 C3 H4 S4 C9
Stable
D2 C3 S4 H4 C9
Not stable

Sample Input 2

2
S1 H1

Sample Output 2

S1 H1
Stable
S1 H1
Stable