import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.InputStreamReader; import java.util.Arrays; public class Main { static boolean batch = false; static boolean readFile = false; static boolean debug = false; static int caseNum = 9; static int T, N, T1; static long money = 2000000; static double[] D; static double[][] Z; static long[] mons; static int[][] s, p, r; public static void main(String[] args) throws Exception { if (batch) { readFile = true; } if (readFile) { if (batch) { long tl = 2000; // TODO long tw = tl - 200; long total = 0; int bidx = 0; int best = 0; int widx = 0; int worst = 1000000000; int re = 0; int tle = 0; for (int z = 0; z < 100; z++) { try { long st = System.currentTimeMillis(); int score = solve(z); long time = System.currentTimeMillis() - st; if (time > tw) { System.out.println(score + "\t" + time + "ms"); if (time > tl) { tle++; } } else { System.out.println(score); } total += score; if (score > best) { best = score; bidx = z; } if (score < worst) { worst = score; widx = z; } } catch (Exception e) { System.out.println(z + ":\t" + e.getMessage()); re++; } } System.out.println("total: " + total); System.out.println("best: " + bidx + ": " + best); System.out.println("worst: " + widx + ": " + worst); System.out.println("RE: " + re); System.out.println("TLE: " + tle); } else { int score = solve(caseNum); System.out.println(score); } } else { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); init(br); solve(br); br.close(); } } static int solve(int z) throws Exception { StringBuilder sb = new StringBuilder(); sb.append(z); while (sb.length() < 4) { sb.insert(0, '0'); } File file = new File("G:\\yuki\\007\\in\\seed_" + sb.toString() + ".txt"); BufferedReader br = new BufferedReader(new FileReader(file)); init(br); int res = solve(br); br.close(); return res; } static void init(BufferedReader br) throws Exception { String[] sa = br.readLine().split(" "); T = Integer.parseInt(sa[0]); N = Integer.parseInt(sa[1]); T1 = T + 1; if (readFile) { D = new double[N]; for (int i = 0; i < N; i++) { D[i] = Double.parseDouble(br.readLine()); } Z = new double[T][N]; for (int i = 0; i < T; i++) { sa = br.readLine().split(" "); for (int j = 0; j < N; j++) { Z[i][j] = Double.parseDouble(sa[j]); } } money = 2000000; } else { money = Integer.parseInt(sa[2]); } mons = new long[T1]; s = new int[T1][N]; p = new int[T1][N]; r = new int[T1][N]; mons[0] = money; } static int solve(BufferedReader br) throws Exception { double[] d = new double[N]; Arrays.fill(d, 1); for (int t = 1; t <= T; t++) { mons[t] = mons[t - 1]; for (int i = 0; i < N; i++) { s[t][i] = s[t - 1][i]; p[t][i] = p[t - 1][i]; r[t][i] = r[t - 1][i]; } if (debug) { System.out.println(Arrays.toString(s[t])); System.out.println(t); System.out.println(mons[t]); System.out.println(Arrays.toString(p[t])); System.out.println(Arrays.toString(r[t])); } boolean done = false; int pmax = 0; for (int i = 0; i < N; i++) { pmax = Math.max(pmax, p[t][i]); } if (pmax < 50 || pmax < 55 && mons[t] >= 8500000) { int x = 0; int need = 500000; for (int i = 1; i <= 5; i++) { if (mons[t] >= need + 500000) { x = i; } else { break; } need *= 2; } if (x >= 2) { output2(x, t); done = true; } } int[] l = new int[N]; double[] exp = new double[N]; double[] pow = new double[N]; for (int i = 0; i < N; i++) { pow[i] = Math.pow(1.05, p[t][i]); } if (!done) { double dsum = 0; for (int i = 0; i < N; i++) { dsum += d[i]; } long can = mons[t] / 500; for (int i = 0; i < N; i++) { if (t >= 33) { l[i] = (int) (can * d[i] / dsum); } else if (r[t][i] == 0 || Math.sqrt(r[t][i]) * pow[i] > ((int) (r[t][i] * 0.3) + 1) * 1.2) { int end = (int) (can * d[i] / dsum); int ng = 0; for (int j = 1; j <= end; j++) { int v1 = r[t][i] + j; double v2 = Math.sqrt(v1) * pow[i] * d[i]; int v3 = (int) (v1 * 0.3) + 1; if (v2 > v3 * 1.2) { ng = 0; l[i] = j; } else { ng++; if (ng == 20) { break; } } } } } output1(l, t); done = true; } for (int i = 0; i < N; i++) { exp[i] = Math.sqrt(r[t][i]) * pow[i]; } boolean res = input(br, t); if (!res) { return -1; } for (int i = 0; i < N; i++) { if (s[t][i] > 0) { double dt = s[t][i] / exp[i]; if (d[i] == 1) { d[i] = dt; } else { d[i] = (d[i] * (t - 1) + dt) / t; } } } } int score = score(); return score; } static void output1(int[] l, int t) { int sum = 0; for (int i = 0; i < N; i++) { sum += l[i]; r[t][i] += l[i]; } if (readFile) { if (sum * 500 > money) { StringBuilder sb = new StringBuilder(); sb.append("money:").append(money); sb.append(" sum:").append(sum); throw new RuntimeException(sb.toString()); } } else { StringBuilder sb = new StringBuilder(); sb.append(1); for (int i = 0; i < N; i++) { sb.append(' ').append(l[i]); } System.out.println(sb.toString()); } money -= sum; } static void output2(int x, int t) { int val = 500000; for (int i = 1; i < x; i++) { val *= 2; } for (int i = 0; i < N; i++) { p[t][i] += x; if (p[t][i] > 60) { p[t][i] = 60; } } if (readFile) { if (val > money) { StringBuilder sb = new StringBuilder(); sb.append("money:").append(money); sb.append(" val:").append(val); throw new RuntimeException(sb.toString()); } } else { System.out.println("2 " + x); } money -= val; } static boolean input(BufferedReader br, int t) throws Exception { if (readFile) { for (int i = 0; i < N; i++) { double v1 = Math.sqrt(r[t][i]) * Math.pow(1.05, p[t][i]); double v2 = v1 * D[i]; double v3 = v2 * Z[t - 1][i]; int v4 = (int) Math.min(r[t][i], v3); s[t][i] = v4; if (r[t][i] != 0) { if (p[t][i] < 60 && v4 >= r[t][i] * 0.3) { p[t][i]++; } if (p[t][i] > -60 && v4 < r[t][i] * 0.1) { p[t][i]--; } } r[t][i] -= v4; money += 1000 * v4; } mons[t] = money; } else { mons[t] = Integer.parseInt(br.readLine()); if (mons[t] == -1) { return false; } String[] sa = br.readLine().split(" "); for (int i = 0; i < N; i++) { s[t][i] = Integer.parseInt(sa[i]); } sa = br.readLine().split(" "); for (int i = 0; i < N; i++) { p[t][i] = Integer.parseInt(sa[i]); } sa = br.readLine().split(" "); for (int i = 0; i < N; i++) { r[t][i] = Integer.parseInt(sa[i]); } } return true; } static int score() { int ret = 0; for (int t = 1; t <= T; t++) { for (int i = 0; i < N; i++) { ret += s[t][i]; } } ret = (ret + 99) / 100; return ret; } }