//#pragma GCC optimize("Ofast") //#pragma GCC optimize "O3,omit-frame-pointer,inline" #include // cout, endl, cin #include // string, to_string, stoi #include // vector #include // min, max, swap, sort, reverse, lower_bound, upper_bound #include // pair, make_pair #include // tuple, make_tuple #include // int64_t, int*_t #include // printf #include // map #include // queue, priority_queue #include // set #include // stack #include // deque #include // unordered_map #include // unordered_set #include // bitset #include // isupper, islower, isdigit, toupper, tolower #include //fixed,setprecision #include //INT_MAX #include //M_PI #include #include // 正規表現 #include #include #include #include #include #include #include #include //複素数 //#include using namespace std; #include using namespace atcoder; //using mint = modint998244353; using ll = long long; using ull = unsigned long long; #define rep(i, n) for (ll i = 0; i < (ll)(n); i++) const int dx[4] = {0, 1, 0, -1}; const int dy[4] = {1, 0, -1, 0}; random_device rnd; mt19937 mt_gen(rnd()); int RandInt(int a, int b) { return a + mt_gen() % (b - a + 1); } const int MAX = 100000000; // スコア計算 int score_function(int N, vector> A, vector C) { vector> B(N, vector(N, 0)); for (int i = 0; i < N; i++) B[N - 1][i] = C[i]; for (int i = N - 2; i >= 0; i--) { for (int j = 0; j <= i; j++) B[i][j] = (B[i + 1][j] + B[i + 1][j + 1]) % MAX; } int max_error = 0; for (int i = 0; i < N; i++) { for (int j = 0; j <= i; j++) max_error = max(max_error, min(abs(A[i][j] - B[i][j]), MAX - abs(A[i][j] - B[i][j]))); } return MAX / 2 - max_error; } int main() { // 入力 int N; cin >> N; vector> A(N, vector(N, 0)); for (int i = 0; i < N; i++) { for (int j = 0; j <= i; j++) cin >> A[i][j]; } // SA double timeLimit = 1.9; auto t0 = chrono::steady_clock::now(); double T0 = 1000, T_end = 1e-9; random_device rnd; mt19937 mt_gen(rnd()); auto RandDouble = [&]() -> double { uniform_real_distribution dist(0.0, 1.0); return dist(mt_gen); }; vector C(N); rep(i, N) C[i] = RandInt(0, MAX - 1); int current_score = score_function(N, A, C); int best_score = current_score; vector best_C = C; while (true) { double elapsed = chrono::duration(chrono::steady_clock::now() - t0).count(); if (elapsed > timeLimit) break; double T = T0 + (T_end - T0) * (elapsed / timeLimit); int r = RandInt(0, N - 1); int old_val = C[r]; int new_val = RandInt(0, MAX - 1); C[r] = new_val; int new_score = score_function(N, A, C); int delta = new_score - current_score; if (delta >= 0 || exp(delta / T) > RandDouble()) { current_score = new_score; if (new_score > best_score) { best_score = new_score; best_C = C; } } else { C[r] = old_val; } } cerr << best_score << endl; rep(i, N) { if (i >= 1) cout << " "; cout << best_C[i]; } cout << endl; return 0; }