結果
| 問題 |
No.5016 Worst Mayor
|
| コンテスト | |
| ユーザー |
e869120
|
| 提出日時 | 2023-04-27 19:39:32 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 189 ms / 2,000 ms |
| コード長 | 4,627 bytes |
| コンパイル時間 | 984 ms |
| コンパイル使用メモリ | 89,444 KB |
| 実行使用メモリ | 26,152 KB |
| スコア | 14,688,501 |
| 平均クエリ数 | 400.00 |
| 最終ジャッジ日時 | 2023-04-29 12:30:53 |
| 合計ジャッジ時間 | 13,201 ms |
|
ジャッジサーバーID (参考情報) |
judge15 / judge11 |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 50 |
ソースコード
#include <iostream>
#include <vector>
#include <tuple>
#include <cmath>
#include <algorithm>
using namespace std;
// Input Information
int N, T;
int A[3009], B[3009], C[3009], D[3009];
int CurrentMoney;
int CurrentCorps;
// Other Variables
int Build[1009];
int Money[2000009];
int Cost[109][109];
int D1[11][12];
int D2[12][11];
vector<tuple<int, int, int, int>> tmp;
// Initialize Money
void Initialize() {
for (int i = 0; i <= 1000; i++) {
for (int j = 0; j < 1000; j++) {
Money[1000 * i + 223 * j] = 60 * j;
}
}
for (int i = 1; i <= 1000; i++) {
Build[i] = (int)(10000000.0 / sqrt(1.0 * i));
}
}
// Get Total Earned Money
int GetEarnedMoney() {
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++) Cost[i][j] = 1000000;
Cost[i][i] = 0;
}
// Initialize Cost
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 10; j++) {
int a1 = (i + 0) * 10 + (j + 0);
int a2 = (i + 1) * 10 + (j + 0);
if (D1[i][j] == 1) {
Cost[a1][a2] = 223;
Cost[a2][a1] = 223;
}
else {
Cost[a1][a2] = 1000;
Cost[a2][a1] = 1000;
}
}
}
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 9; j++) {
int a1 = (i + 0) * 10 + (j + 0);
int a2 = (i + 0) * 10 + (j + 1);
if (D2[i][j] == 1) {
Cost[a1][a2] = 223;
Cost[a2][a1] = 223;
}
else {
Cost[a1][a2] = 1000;
Cost[a2][a1] = 1000;
}
}
}
// Warshall-Floyd
for (int k = 0; k < 100; k++) {
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++) Cost[i][j] = min(Cost[i][j], Cost[i][k] + Cost[k][j]);
}
}
int sum = 0;
for (int i = 1; i <= N; i++) {
int pos1 = (A[i] - 1) * 10 + (B[i] - 1);
int pos2 = (C[i] - 1) * 10 + (D[i] - 1);
sum += Money[Cost[pos1][pos2]];
}
return sum;
}
// Set Rectangle: Case 1
void SetRect1(int L, int R) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 10; j++) D1[i][j] = 0;
}
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 9; j++) D2[i][j] = 0;
}
tmp.clear();
vector<int> ord = { 4, 3, 5, 2, 6, 1, 7, 0, 8 };
for (int i = 0; i < 9; i++) { D1[ord[i]][L] = 1; tmp.push_back(make_tuple(ord[i], L, ord[i] + 1, L)); }
for (int i = 0; i < 9; i++) { D1[ord[i]][R] = 1; tmp.push_back(make_tuple(ord[i], R, ord[i] + 1, R)); }
for (int i = L; i < R; i++) { D2[0][i] = 1; tmp.push_back(make_tuple(0, i, 0, i + 1)); }
for (int i = L; i < R; i++) { D2[9][i] = 1; tmp.push_back(make_tuple(9, i, 9, i + 1)); }
}
// Set Rectangle: Case 2
void SetRect2(int L, int R) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 10; j++) D1[i][j] = 0;
}
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 9; j++) D2[i][j] = 0;
}
tmp.clear();
vector<int> ord = { 4, 3, 5, 2, 6, 1, 7, 0, 8 };
for (int i = 0; i < 9; i++) { D2[L][ord[i]] = 1; tmp.push_back(make_tuple(L, ord[i], L, ord[i] + 1)); }
for (int i = 0; i < 9; i++) { D2[R][ord[i]] = 1; tmp.push_back(make_tuple(R, ord[i], R, ord[i] + 1)); }
for (int i = L; i < R; i++) { D1[i][0] = 1; tmp.push_back(make_tuple(i, 0, i + 1, 0)); }
for (int i = L; i < R; i++) { D1[i][9] = 1; tmp.push_back(make_tuple(i, 9, i + 1, 9)); }
}
int main() {
// Input
Initialize();
cin >> N >> T;
for (int i = 1; i <= N; i++) cin >> A[i] >> B[i] >> C[i] >> D[i];
// Brute Force Type 1 Rectangle
int Maximum = 0;
tuple<int, int, int> MaxID = make_tuple(-1, -1, -1);
for (int i = 0; i < 10; i++) {
for (int j = i + 1; j < 10; j++) {
SetRect1(i, j);
int Score = GetEarnedMoney();
if (Maximum < Score) {
Maximum = Score;
MaxID = make_tuple(1, i, j);
}
}
}
// Brute Force Type 2 Rectangle
for (int i = 0; i < 10; i++) {
for (int j = i + 1; j < 10; j++) {
SetRect2(i, j);
int Score = GetEarnedMoney();
if (Maximum < Score) {
Maximum = Score;
MaxID = make_tuple(2, i, j);
}
}
}
// Get tmp
int CountRoads = 0;
int BuiltRoads = 0;
if (get<0>(MaxID) == 1) SetRect1(get<1>(MaxID), get<2>(MaxID));
if (get<0>(MaxID) == 2) SetRect2(get<1>(MaxID), get<2>(MaxID));
// Answer Query
for (int i = 1; i <= T; i++) {
cin >> CurrentMoney >> CurrentCorps;
if (CurrentMoney == -1 && CurrentCorps == -1) break;
fprintf(stderr, "Turn =% 4d, Money=% 10d, Corps =% 3d, Roads =% 3d/%d\n", i, CurrentMoney, CurrentCorps, BuiltRoads, CountRoads);
// Get Acts
if (i <= 30) {
cout << "3" << endl;
}
else if (CountRoads == (int)tmp.size()) {
cout << "3" << endl;
}
else if (CurrentMoney < Build[CurrentCorps]) {
cout << "2" << endl;
}
else {
cout << "1 " << get<0>(tmp[BuiltRoads]) + 1 << " " << get<1>(tmp[BuiltRoads]) + 1 << " " << get<2>(tmp[BuiltRoads]) + 1 << " " << get<3>(tmp[BuiltRoads]) + 1 << endl;
}
}
return 0;
}
e869120