Submission #2106800


Source Code Expand

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

/**
 * Hack To The Future 2018
 *
 * @author tsukammo
 */
public class Main {

	Scanner sc = new Scanner(System.in);

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

	// 制約
	final static int N = 100, row = 100, col = 100, pnum = 1000;

	void solve() {
		input();
		init();
		simulate(); // new
		output();
	}

	Random rnd = new Random(20180217);
	int[][] ans = new int[1000][3];

	void init() {
		for (int i = 0; i < pnum; i++) {
			int x = rnd.nextInt(100);
			int y = rnd.nextInt(100);
			int h = rnd.nextInt(100) + 1;
			ans[i][0] = x;
			ans[i][1] = y;
			ans[i][2] = h;
		}
	}

	static final long timeLimit = 5500;

	void simulate() {
		long st = System.currentTimeMillis();
		long et = st + timeLimit;

		int[][] bestOutput = new int[1000][3];

		for (int i = 0; i < bestOutput.length; i++) {
			bestOutput[i] = Arrays.copyOf(ans[i], ans[i].length);
		}

		int[][] diff = makeDiff(bestOutput);
		int bestScore = 0;
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				bestScore += Math.abs(diff[i][j]);
			}
		}

		int loopCount = 0;
		while (System.currentTimeMillis() < et) {
			loopCount++;
			int[] tmpOutput = new int[3];
			int[] beforeOutput = new int[3];
			int n = rnd.nextInt(1000);
			beforeOutput[0] = bestOutput[n][0];
			beforeOutput[1] = bestOutput[n][1];
			beforeOutput[2] = bestOutput[n][2];

			int x = rnd.nextInt(100);
			int y = rnd.nextInt(100);
			int h = rnd.nextInt(100) + 1;
			tmpOutput[0] = x;
			tmpOutput[1] = y;
			tmpOutput[2] = h;

			updateDiff(diff, beforeOutput, tmpOutput);
			int tmpScore = 0;
			for (int i = 0; i < row; i++) {
				for (int j = 0; j < col; j++) {
					tmpScore += Math.abs(diff[i][j]);
				}
			}

			if (bestScore > tmpScore) {
				bestScore = tmpScore;
				bestOutput[n] = tmpOutput;
			} else {
				// rollback
				updateDiff(diff, tmpOutput, beforeOutput);
			}
		}
		System.err.println("loop:" + loopCount);
		for (int i = 0; i < bestOutput.length; i++) {
			ans[i] = Arrays.copyOf(bestOutput[i], bestOutput[i].length);
		}
	}

	// 差分更新
	void updateDiff(int[][] diff, int[] before, int[] after) {

		// subtract
		int x = before[0];
		int y = before[1];
		int h = before[2];
		diff[x][y] += h;
		for (int plus = 1; plus < h; plus++) {
			int d = h - plus;
			x = before[0];
			y = before[1] - d;
			for (int j = 0; j < dx.length; j++) {
				for (int k = 0; k < d; k++) {
					x = x + dx[j];
					y = y + dy[j];
					if (outMap(x, y)) {
						continue;
					}
					diff[x][y] += plus;
				}
			}
		}

		// add
		x = after[0];
		y = after[1];
		h = after[2];
		diff[x][y] -= h;
		for (int plus = 1; plus < h; plus++) {
			int d = h - plus;
			x = after[0];
			y = after[1] - d;
			for (int j = 0; j < dx.length; j++) {
				for (int k = 0; k < d; k++) {
					x = x + dx[j];
					y = y + dy[j];
					if (outMap(x, y)) {
						continue;
					}
					diff[x][y] -= plus;
				}
			}
		}
	}

	int[][] makeDiff(int[][] output) {
		int[][] ret = new int[row][col];
		int[][] ansMap = new int[row][col];

		for (int i = 0; i < output.length; i++) {
			int x = output[i][0];
			int y = output[i][1];
			int h = output[i][2];
			ansMap[x][y] += h;
			for (int plus = 1; plus < h; plus++) {
				int d = h - plus;
				x = output[i][0];
				y = output[i][1] - d;
				for (int j = 0; j < dx.length; j++) {
					for (int k = 0; k < d; k++) {
						x = x + dx[j];
						y = y + dy[j];
						if (outMap(x, y)) {
							continue;
						}
						ansMap[x][y] += plus;
					}
				}
			}
		}

		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				ret[i][j] = map[i][j] - ansMap[i][j];
			}
		}
		return ret;
	}

	// 山の外周に沿って斜め移動
	final static int dx[] = new int[] { 1, -1, -1, 1 };
	final static int dy[] = new int[] { 1, 1, -1, -1 };

	// シミュレータ
	int eval(int[][] output) {
		int ret = 0;
		int[][] ansMap = new int[row][col];

		for (int i = 0; i < output.length; i++) {
			int x = output[i][0];
			int y = output[i][1];
			int h = output[i][2];
			ansMap[x][y] += h;
			for (int plus = 1; plus < h; plus++) {
				int d = h - plus;
				x = output[i][0];
				y = output[i][1] - d;
				for (int j = 0; j < dx.length; j++) {
					for (int k = 0; k < d; k++) {
						x = x + dx[j];
						y = y + dy[j];
						if (outMap(x, y)) {
							continue;
						}
						ansMap[x][y] += plus;
					}
				}
			}
		}

		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				ret += Math.abs(map[i][j] - ansMap[i][j]);
			}
		}
		return ret;
	}

	boolean outMap(int x, int y) {
		return !(x > -1 && y > -1 && x < row && y < col);
	}

	int[][] map = new int[row][col];

	void input() {
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				map[j][i] = sc.nextInt();
			}
		}
	}

	void output() {
		// 乱択した山を出力する
		System.out.println(ans.length);
		for (int i = 0; i < ans.length; i++) {
			System.out.println(ans[i][0] + " " + ans[i][1] + " " + ans[i][2]);
		}
	}
}

Submission Info

Submission Time
Task A - 山型足し算
User tsukammo
Language Java8 (OpenJDK 1.8.0)
Score 9990842862
Code Size 5319 Byte
Status AC
Exec Time 5730 ms
Memory 36924 KB

Judge Result

Set Name Sample All
Score / Max Score 199797533 / 200000000 9791045329 / 9800000000
Status
AC × 1
AC × 49
Set Name Test Cases
Sample example_01.txt
All subtask_01_01.txt, subtask_01_02.txt, subtask_01_03.txt, subtask_01_04.txt, subtask_01_05.txt, subtask_01_06.txt, subtask_01_07.txt, subtask_01_08.txt, subtask_01_09.txt, subtask_01_10.txt, subtask_01_11.txt, subtask_01_12.txt, subtask_01_13.txt, subtask_01_14.txt, subtask_01_15.txt, subtask_01_16.txt, subtask_01_17.txt, subtask_01_18.txt, subtask_01_19.txt, subtask_01_20.txt, subtask_01_21.txt, subtask_01_22.txt, subtask_01_23.txt, subtask_01_24.txt, subtask_01_25.txt, subtask_01_26.txt, subtask_01_27.txt, subtask_01_28.txt, subtask_01_29.txt, subtask_01_30.txt, subtask_01_31.txt, subtask_01_32.txt, subtask_01_33.txt, subtask_01_34.txt, subtask_01_35.txt, subtask_01_36.txt, subtask_01_37.txt, subtask_01_38.txt, subtask_01_39.txt, subtask_01_40.txt, subtask_01_41.txt, subtask_01_42.txt, subtask_01_43.txt, subtask_01_44.txt, subtask_01_45.txt, subtask_01_46.txt, subtask_01_47.txt, subtask_01_48.txt, subtask_01_49.txt
Case Name Status Exec Time Memory
example_01.txt AC 5723 ms 34012 KB
subtask_01_01.txt AC 5705 ms 35988 KB
subtask_01_02.txt AC 5721 ms 33156 KB
subtask_01_03.txt AC 5726 ms 33820 KB
subtask_01_04.txt AC 5721 ms 34976 KB
subtask_01_05.txt AC 5716 ms 36104 KB
subtask_01_06.txt AC 5707 ms 36144 KB
subtask_01_07.txt AC 5721 ms 34944 KB
subtask_01_08.txt AC 5715 ms 33508 KB
subtask_01_09.txt AC 5712 ms 34272 KB
subtask_01_10.txt AC 5714 ms 35824 KB
subtask_01_11.txt AC 5716 ms 33580 KB
subtask_01_12.txt AC 5702 ms 34240 KB
subtask_01_13.txt AC 5723 ms 36488 KB
subtask_01_14.txt AC 5705 ms 36264 KB
subtask_01_15.txt AC 5719 ms 33660 KB
subtask_01_16.txt AC 5706 ms 35152 KB
subtask_01_17.txt AC 5722 ms 35748 KB
subtask_01_18.txt AC 5714 ms 34224 KB
subtask_01_19.txt AC 5722 ms 34532 KB
subtask_01_20.txt AC 5714 ms 36280 KB
subtask_01_21.txt AC 5714 ms 35132 KB
subtask_01_22.txt AC 5712 ms 36136 KB
subtask_01_23.txt AC 5723 ms 33652 KB
subtask_01_24.txt AC 5709 ms 33416 KB
subtask_01_25.txt AC 5722 ms 36468 KB
subtask_01_26.txt AC 5703 ms 34496 KB
subtask_01_27.txt AC 5711 ms 34180 KB
subtask_01_28.txt AC 5716 ms 33020 KB
subtask_01_29.txt AC 5716 ms 36924 KB
subtask_01_30.txt AC 5730 ms 34620 KB
subtask_01_31.txt AC 5704 ms 35528 KB
subtask_01_32.txt AC 5706 ms 34344 KB
subtask_01_33.txt AC 5712 ms 36484 KB
subtask_01_34.txt AC 5715 ms 35096 KB
subtask_01_35.txt AC 5713 ms 34440 KB
subtask_01_36.txt AC 5714 ms 34716 KB
subtask_01_37.txt AC 5725 ms 33884 KB
subtask_01_38.txt AC 5720 ms 32572 KB
subtask_01_39.txt AC 5714 ms 35060 KB
subtask_01_40.txt AC 5701 ms 36840 KB
subtask_01_41.txt AC 5717 ms 36744 KB
subtask_01_42.txt AC 5713 ms 36580 KB
subtask_01_43.txt AC 5724 ms 34596 KB
subtask_01_44.txt AC 5716 ms 35076 KB
subtask_01_45.txt AC 5724 ms 33520 KB
subtask_01_46.txt AC 5721 ms 34492 KB
subtask_01_47.txt AC 5715 ms 35264 KB
subtask_01_48.txt AC 5705 ms 36156 KB
subtask_01_49.txt AC 5722 ms 33928 KB