Problem:
メリーゴーランド

遊園地にあるメリーゴーランドはご存じでしょう。大きな円盤の上に馬や馬車などの乗り物が固定されていて、円盤が回転すると同時に乗り物が上下に揺れる、定番の遊具です。ある遊園地のメリーゴーランドは、４人乗りの馬車が２台、２人乗りの車２台、１人乗りの馬が４台、計８台の乗り物が図１のような順序で備えられています。そして、遊園地においでのお客様は、図１に示す乗り場０〜７のどこかで待つようになっています。

この遊園地のメリーゴーランドは、かならず乗り物が乗り場にぴったりと合う位置に停止します。そして、０〜７のそれぞれで待っているお客さまは、目の前にとまった乗り物に乗ることになっています。急いで他の乗り場へ移動してそこから乗るということはできません。効率よく、お客さまにたのしんでいただくためには、メリーゴーランドの停止する位置をうまく調整して、乗れないお客さまをできるだけ少なくするようにしなければなりません。

乗り場０〜７で待っているお客さまの人数を読み込んで、どの位置にどの乗り物が来るように止めれば乗れないお客さまが最も少なくなるかを出力するプログラムを作成してください。

入力

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

p0 p1 p2 p3 p4 p5 p6 p7

乗り場 0, 1, ..., 7 で待っているお客様の人数を表す整数 p0, p1,... , p7 ( 0 ≤ pi ≤ 10,000) が空白区切りで１行に与えられます。

出力

メリーゴーランドの乗り物の馬車を 4、車を 2、馬を 1 で表すこととします。乗り場 0, 1, ... , 7 にとめる乗り物を、それぞれ c0, c1,..., c7 とします。データセットごとに、c0, c1,..., c7 を空白区切りで 1 行に出力します。

なお、乗れなくなるお客さまが最小となるとめ方が複数ある場合は、c0c1c2c3c4c5c6c7 を 8 桁の整数 V とみなし、V が最小となるとめ方を選ぶものとします。

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

Sample Input

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

Output for the Sample Input

1 4 1 4 1 2 1 2
4 1 4 1 2 1 2 1

Solution in JAVA (judge verdict: Accepted)

import java.util.*;

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

	public void run() {
		int[] merry=new int[]{1,4,1,4,1,2,1,2};
		while(sc.hasNext()){
			int index=0,max=-1,val=0;
			int[] people=new int[]{sc.nextInt(),
				sc.nextInt(),sc.nextInt(),sc.nextInt(),sc.nextInt()
				,sc.nextInt(),sc.nextInt(),sc.nextInt()};
			for(int i=0;i<8;i++){
				int sum=0;
				for(int j=0;j<8;j++){
					sum+=Math.min(merry[(i+j)%8],people[j]);
				}
				if(sum>max){
					index=i;
					max=sum;
					int v=0;
					for(int j=0;j<8;j++){
						v=merry[(i+j)%8]+v*10;
					}
					val=v;
				}else if(sum==max){
					int v=0;
					for(int j=0;j<8;j++){
						v=merry[(i+j)%8]+v*10;
					}
					if(v<val){
						index=i;
						max=sum;
						val=v;
					}
				}
			}
			for(int i=0;i<8;i++){
				pr((i==0?"":" ")+merry[(i+index)%8]);
			}
			ln();
		}
	}

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

	public static void pr(Object o) {
		System.out.print(o);
	}

	public static void ln(Object o) {
		System.out.println(o);
	}

	public static void ln() {
		System.out.println();
	}
}

class P {
	double x;
	double y;

	P(double _x, double _y) {
		x = _x;
		y = _y;
	}

	public static final P Xunit = new P(1, 0);
	public static final P Yunit = new P(0, 1);

	public static double dot(P a, P b) {
		return a.x * b.x + a.y * b.y;
	}

	public static double cross(P a, P b) {
		return a.x * b.y - a.y * b.x;
	}

	public static boolean isParallel(P a1, P a2, P b1, P b2) {
		return Math.abs(cross(a2.s(a1), b2.s(b1))) < Double.MIN_NORMAL;
	}

	public static boolean isVertical(P a1, P a2, P b1, P b2) {
		return Math.abs(dot(a2.s(a1), b2.s(b1))) < Double.MIN_NORMAL;
	}

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

	public P s(P a) {
		return new P(x - a.x, y - a.y);
	}

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

	public double arg() {
		double s = Math.acos(x / norm());
		return y > 0 ? s : 2 * Math.PI - s;
	}

	public P rotate(double t) {
		return new P(Math.cos(t) * this.x - Math.sin(t) * this.y, Math.sin(t)
				* this.x + Math.cos(t) * this.y);
	}

	public static int ccw(P a, P b, P c) {
		if (P.cross(b.s(a), c.s(a)) > Double.MIN_NORMAL) {
			return 1;
		}
		if (cross(b.s(a), c.s(a)) < -Double.MIN_NORMAL) {
			return -1;
		}
		if (dot(b, c) < -Double.MIN_NORMAL)
			return 2;
		if (b.norm() < c.norm() - Double.MIN_NORMAL)
			return -2;
		return 0;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof P) {
			P p = (P) obj;
			return x == p.x && y == p.y;
		}
		return false;
	}

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