Submission #33976417
Source Code Expand
#include <cassert>
#include <iostream>
#include <map>
#include <random>
#include <utility>
#include <vector>
using namespace std;
struct MoveAction {
int before_row, before_col, after_row, after_col;
MoveAction(int before_row, int before_col, int after_row, int after_col) :
before_row(before_row), before_col(before_col), after_row(after_row), after_col(after_col) {}
};
struct ConnectAction {
int c1_row, c1_col, c2_row, c2_col;
ConnectAction(int c1_row, int c1_col, int c2_row, int c2_col) :
c1_row(c1_row), c1_col(c1_col), c2_row(c2_row), c2_col(c2_col) {}
};
struct Result {
vector<MoveAction> move;
vector<ConnectAction> connect;
Result(const vector<MoveAction> &move, const vector<ConnectAction> &con) : move(move), connect(con) {}
};
struct Solver {
static constexpr char USED = 'x';
static constexpr int DR[4] = {0, 1, 0, -1};
static constexpr int DC[4] = {1, 0, -1, 0};
int N, K;
int action_count_limit;
mt19937 engine;
vector<string> field;
Solver(int N, int K, const vector<string> &field, int seed = 0) :
N(N), K(K), action_count_limit(K * 100), field(field)
{
engine.seed(seed);
}
bool can_move(int row, int col, int dir) const
{
int nrow = row + DR[dir];
int ncol = col + DC[dir];
if (0 <= nrow && nrow < N && 0 <= ncol && ncol < N) {
return field[nrow][ncol] == '0';
}
return false;
}
vector<MoveAction> move(int move_limit = -1)
{
vector<MoveAction> ret;
if (move_limit == -1) {
move_limit = K * 50;
}
for (int i = 0; i < move_limit; i++) {
int row = engine() % N;
int col = engine() % N;
int dir = engine() % 4;
if (field[row][col] != '0' && can_move(row, col, dir)) {
swap(field[row][col], field[row + DR[dir]][col + DC[dir]]);
ret.emplace_back(row, col, row + DR[dir], col + DC[dir]);
action_count_limit--;
}
}
return ret;
}
bool can_connect(int row, int col, int dir) const
{
int nrow = row + DR[dir];
int ncol = col + DC[dir];
while (0 <= nrow && nrow < N && 0 <= ncol && ncol < N) {
if (field[nrow][ncol] == field[row][col]) {
return true;
} else if (field[nrow][ncol] != '0') {
return false;
}
nrow += DR[dir];
ncol += DC[dir];
}
return false;
}
ConnectAction line_fill(int row, int col, int dir)
{
int nrow = row + DR[dir];
int ncol = col + DC[dir];
while (0 <= nrow && nrow < N && 0 <= ncol && ncol < N) {
if (field[nrow][ncol] == field[row][col]) {
return ConnectAction(row, col, nrow, ncol);
}
assert(field[nrow][ncol] == '0');
field[nrow][ncol] = USED;
nrow += DR[dir];
ncol += DC[dir];
}
assert(false);
}
vector<ConnectAction> connect()
{
vector<ConnectAction> ret;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (field[i][j] != '0' && field[i][j] != 'x') {
for (int dir = 0; dir < 2; dir++) {
if (can_connect(i, j, dir)) {
ret.push_back(line_fill(i, j, dir));
action_count_limit--;
if (action_count_limit <= 0) {
return ret;
}
}
}
}
}
}
return ret;
}
Result solve()
{
// create random moves
auto moves = move();
// from each computer, connect to right and/or bottom if it will reach the same type
auto connects = connect();
return Result(moves, connects);
}
};
struct UnionFind {
map<pair<int,int>, pair<int, int>> parent;
UnionFind() :parent() {}
pair<int, int> find(pair<int, int> x)
{
if (parent.find(x) == parent.end()) {
parent[x] = x;
return x;
} else if (parent[x] == x) {
return x;
} else {
parent[x] = find(parent[x]);
return parent[x];
}
}
void unite(pair<int, int> x, pair<int, int> y)
{
x = find(x);
y = find(y);
if (x != y) {
parent[x] = y;
}
}
};
int calc_score(int N, vector<string> field, const Result &res)
{
for (auto r : res.move) {
assert(field[r.before_row][r.before_col] != '0');
assert(field[r.after_row][r.after_col] == '0');
swap(field[r.before_row][r.before_col], field[r.after_row][r.after_col]);
}
UnionFind uf;
for (auto r : res.connect) {
pair<int, int> p1(r.c1_row, r.c1_col), p2(r.c2_row, r.c2_col);
uf.unite(p1, p2);
}
vector<pair<int, int>> computers;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (field[i][j] != '0') {
computers.emplace_back(i, j);
}
}
}
int score = 0;
for (int i = 0; i < (int)computers.size(); i++) {
for (int j = i+1; j < (int)computers.size(); j++) {
auto c1 = computers[i];
auto c2 = computers[j];
if (uf.find(c1) == uf.find(c2)) {
score += (field[c1.first][c1.second] == field[c2.first][c2.second]) ? 1 : -1;
}
}
}
return max(score, 0);
}
void print_answer(const Result &res)
{
cout << res.move.size() << endl;
for (auto m : res.move) {
cout << m.before_row << " " << m.before_col << " "
<< m.after_row << " " << m.after_col << endl;
}
cout << res.connect.size() << endl;
for (auto m : res.connect) {
cout << m.c1_row << " " << m.c1_col << " "
<< m.c2_row << " " << m.c2_col << endl;
}
}
int main()
{
int N, K;
cin >> N >> K;
vector<string> field(N);
for (int i = 0; i < N; i++) {
cin >> field[i];
}
Solver s(N, K, field);
auto ret = s.solve();
cerr << "Score = " << calc_score(N, field, ret) << endl;
print_answer(ret);
return 0;
}
Submission Info
| Submission Time |
|
| Task |
A - Server Room |
| User |
NHS93 |
| Language |
C++ (GCC 9.2.1) |
| Score |
26047 |
| Code Size |
6641 Byte |
| Status |
AC |
| Exec Time |
41 ms |
| Memory |
3704 KiB |
Judge Result
| Set Name |
test_all |
| Score / Max Score |
26047 / 1237500 |
| Status |
|
| Set Name |
Test Cases |
| test_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, subtask_01_50.txt |
| Case Name |
Status |
Exec Time |
Memory |
| subtask_01_01.txt |
AC |
41 ms |
3564 KiB |
| subtask_01_02.txt |
AC |
36 ms |
3656 KiB |
| subtask_01_03.txt |
AC |
11 ms |
3644 KiB |
| subtask_01_04.txt |
AC |
33 ms |
3668 KiB |
| subtask_01_05.txt |
AC |
17 ms |
3492 KiB |
| subtask_01_06.txt |
AC |
32 ms |
3668 KiB |
| subtask_01_07.txt |
AC |
10 ms |
3600 KiB |
| subtask_01_08.txt |
AC |
32 ms |
3652 KiB |
| subtask_01_09.txt |
AC |
25 ms |
3700 KiB |
| subtask_01_10.txt |
AC |
27 ms |
3640 KiB |
| subtask_01_11.txt |
AC |
9 ms |
3492 KiB |
| subtask_01_12.txt |
AC |
10 ms |
3552 KiB |
| subtask_01_13.txt |
AC |
26 ms |
3700 KiB |
| subtask_01_14.txt |
AC |
32 ms |
3664 KiB |
| subtask_01_15.txt |
AC |
15 ms |
3536 KiB |
| subtask_01_16.txt |
AC |
40 ms |
3624 KiB |
| subtask_01_17.txt |
AC |
39 ms |
3508 KiB |
| subtask_01_18.txt |
AC |
29 ms |
3664 KiB |
| subtask_01_19.txt |
AC |
9 ms |
3644 KiB |
| subtask_01_20.txt |
AC |
12 ms |
3616 KiB |
| subtask_01_21.txt |
AC |
9 ms |
3648 KiB |
| subtask_01_22.txt |
AC |
11 ms |
3648 KiB |
| subtask_01_23.txt |
AC |
23 ms |
3680 KiB |
| subtask_01_24.txt |
AC |
35 ms |
3668 KiB |
| subtask_01_25.txt |
AC |
25 ms |
3560 KiB |
| subtask_01_26.txt |
AC |
24 ms |
3640 KiB |
| subtask_01_27.txt |
AC |
31 ms |
3512 KiB |
| subtask_01_28.txt |
AC |
29 ms |
3660 KiB |
| subtask_01_29.txt |
AC |
39 ms |
3568 KiB |
| subtask_01_30.txt |
AC |
35 ms |
3668 KiB |
| subtask_01_31.txt |
AC |
36 ms |
3624 KiB |
| subtask_01_32.txt |
AC |
34 ms |
3564 KiB |
| subtask_01_33.txt |
AC |
16 ms |
3552 KiB |
| subtask_01_34.txt |
AC |
33 ms |
3620 KiB |
| subtask_01_35.txt |
AC |
35 ms |
3704 KiB |
| subtask_01_36.txt |
AC |
35 ms |
3560 KiB |
| subtask_01_37.txt |
AC |
29 ms |
3660 KiB |
| subtask_01_38.txt |
AC |
38 ms |
3552 KiB |
| subtask_01_39.txt |
AC |
34 ms |
3700 KiB |
| subtask_01_40.txt |
AC |
26 ms |
3500 KiB |
| subtask_01_41.txt |
AC |
10 ms |
3604 KiB |
| subtask_01_42.txt |
AC |
10 ms |
3640 KiB |
| subtask_01_43.txt |
AC |
18 ms |
3608 KiB |
| subtask_01_44.txt |
AC |
16 ms |
3564 KiB |
| subtask_01_45.txt |
AC |
15 ms |
3668 KiB |
| subtask_01_46.txt |
AC |
12 ms |
3576 KiB |
| subtask_01_47.txt |
AC |
27 ms |
3668 KiB |
| subtask_01_48.txt |
AC |
35 ms |
3576 KiB |
| subtask_01_49.txt |
AC |
25 ms |
3560 KiB |
| subtask_01_50.txt |
AC |
30 ms |
3688 KiB |