Submission #39204745
Source Code Expand
import std;
enum Response {
bedrock = 0,
broken = 1,
finish = 2,
invalid = -1
}
struct Coordinate {
int x, y;
int calculateDistance(Coordinate that) {
return abs(this.x-that.x) + abs(this.y-that.y);
}
}
int N, W, K, C;
Coordinate[] sources, houses;
enum int P = 100;
enum int TIME_LIMIT = 4500;
struct State {
ulong size;
Coordinate[] coordinates;
Coordinate[] starts, goals;
int[] arr;
}
State resultState;
int[] sourceNumbers;
void preprocess() {
sourceNumbers = new int[](K);
auto distances = new int[](K);
distances[] = int.max;
foreach (i; 0 .. K) {
foreach (j; 0 .. W) {
int distance = houses[i].calculateDistance(sources[j]);
if (distances[i] > distance) {
distances[i] = distance;
sourceNumbers[i] = j;
}
}
}
}
const int[4] dx = [-1, 0, 1, 0], dy = [0, 1, 0, -1];
struct Field {
State state;
int[] arr;
bool[][] isBroken, isSource;
this(int[] a) {
this.arr = a;
this.isBroken = new bool[][](N, N);
this.isSource = new bool[][](N, N);
foreach (i; 0 .. W) {
this.isSource[sources[i].x][sources[i].y] = true;
}
calculate();
}
Coordinate breadthFirstSearch(Coordinate start) {
auto distances = new int[][](N, N);
foreach (j; 0 .. N) distances[j][] = int.max;
Coordinate[] queue;
queue ~= start;
distances[start.x][start.y] = 1;
while (!queue.empty) {
auto f = queue.front;
queue.popFront;
if (this.isSource[f.x][f.y]) {
return f;
}
foreach (i; 0 .. 4) {
int nx = f.x + dx[i], ny = f.y + dy[i];
if (nx < 0 || N <= nx || ny < 0 || N <= ny) continue;
if (distances[nx][ny] <= distances[f.x][f.y] + 1) continue;
distances[nx][ny] = distances[f.x][f.y] + 1;
queue ~= Coordinate(nx, ny);
}
}
return Coordinate(-1, -1);
}
bool isMoveX(Coordinate start, Coordinate goal) {
int countX;
foreach (i; min(start.x, goal.x) .. max(start.x, goal.x)) {
if (!this.isBroken[i][start.y]) ++countX;
}
foreach (i; min(start.y, goal.y) .. max(start.y, goal.y)+1) {
if (!this.isBroken[goal.x][i]) ++countX;
}
int countY;
foreach (i; min(start.y, goal.y) .. max(start.y, goal.y)) {
if (!this.isBroken[start.x][i]) ++countY;
}
foreach (i; min(start.x, goal.x) .. max(start.x, goal.x)+1) {
if (!this.isBroken[i][goal.y]) ++countY;
}
return countX <= countY;
}
void move(Coordinate start, Coordinate goal, bool isX) {
int sx = start.x, sy = start.y;
int gx = goal.x, gy = goal.y;
if (isX) {
if (sx <= gx) {
foreach (i; sx .. gx) {
if (this.isBroken[i][sy]) return;
this.state.coordinates ~= Coordinate(i, sy);
this.isBroken[i][sy] = true;
this.isSource[i][sy] = true;
}
}
else {
for (int i = sx; i > gx; --i) {
if (this.isBroken[i][sy]) return;
this.state.coordinates ~= Coordinate(i, sy);
this.isBroken[i][sy] = true;
this.isSource[i][sy] = true;
}
}
if (sy <= gy) {
foreach (i; sy .. gy+1) {
if (this.isBroken[gx][i]) return;
this.state.coordinates ~= Coordinate(gx, i);
this.isBroken[gx][i] = true;
this.isSource[gx][i] = true;
}
}
else {
for (int i = sy; i >= gy; --i) {
if (this.isBroken[gx][i]) return;
this.state.coordinates ~= Coordinate(gx, i);
this.isBroken[gx][i] = true;
this.isSource[gx][i] = true;
}
}
}
else {
if (sy <= gy) {
foreach (i; sy .. gy) {
if (this.isBroken[sx][i]) return;
this.state.coordinates ~= Coordinate(sx, i);
this.isBroken[sx][i] = true;
this.isSource[sx][i] = true;
}
}
else {
for (int i = sy; i > gy; --i) {
if (this.isBroken[sx][i]) return;
this.state.coordinates ~= Coordinate(sx, i);
this.isBroken[sx][i] = true;
this.isSource[sx][i] = true;
}
}
if (sx <= gx) {
foreach (i; sx .. gx+1) {
if (this.isBroken[i][gy]) return;
this.state.coordinates ~= Coordinate(i, gy);
this.isBroken[i][gy] = true;
this.isSource[i][gy] = true;
}
}
else {
for (int i = sx; i >= gx; --i) {
if (this.isBroken[i][gy]) return;
this.state.coordinates ~= Coordinate(i, gy);
this.isBroken[i][gy] = true;
this.isSource[i][gy] = true;
}
}
}
}
void calculate() {
foreach (i, a; this.arr) {
Coordinate goal = sources[sourceNumbers[a]];
if (i > 0) {
goal = breadthFirstSearch(houses[a]);
}
state.starts ~= houses[a];
state.goals ~= goal;
bool isX = isMoveX(houses[a], goal);
move(houses[a], goal, isX);
}
state.size = state.coordinates.length;
state.arr = arr;
}
}
void solve() {
SysTime startTime = Clock.currTime;
resultState.size = ulong.max;
preprocess();
auto rnd = MinstdRand0(42);
auto numbers = iota(K).array;
while ((Clock.currTime - startTime).total!"msecs" < dur!"msecs"(TIME_LIMIT).total!"msecs") {
auto arr = numbers.dup.randomShuffle(rnd).array;
auto field = new Field(arr);
if (resultState.size > field.state.size) {
resultState = field.state;
}
}
foreach (coordinate; resultState.coordinates) {
Response response = Response.bedrock;
while (response == Response.bedrock) {
writefln("%d %d %d", coordinate.x, coordinate.y, P);
stdout.flush;
int input;
readf("%d\n", input);
if (input == 1) {
response = Response.broken;
}
else if (input == 2) {
response = Response.finish;
}
else if (input == -1) {
response = Response.invalid;
}
}
if (response == Response.finish || response == Response.invalid) {
return;
}
}
}
void main() {
readf("%d %d %d %d\n", N, W, K, C);
sources.length = W;
foreach (i; 0 .. W) readf("%d %d\n", sources[i].x, sources[i].y);
houses.length = K;
foreach (i; 0 .. K) readf("%d %d\n", houses[i].x, houses[i].y);
solve();
}
Submission Info
Submission Time |
|
Task |
A - Excavation |
User |
kokatsu |
Language |
D (LDC 1.20.1) |
Score |
13961073 |
Code Size |
7700 Byte |
Status |
AC |
Exec Time |
4553 ms |
Memory |
11460 KiB |
Judge Result
Set Name |
test_ALL |
Score / Max Score |
13961073 / 50000000000 |
Status |
|
Set Name |
Test Cases |
test_ALL |
test_0000.txt, test_0001.txt, test_0002.txt, test_0003.txt, test_0004.txt, test_0005.txt, test_0006.txt, test_0007.txt, test_0008.txt, test_0009.txt, test_0010.txt, test_0011.txt, test_0012.txt, test_0013.txt, test_0014.txt, test_0015.txt, test_0016.txt, test_0017.txt, test_0018.txt, test_0019.txt, test_0020.txt, test_0021.txt, test_0022.txt, test_0023.txt, test_0024.txt, test_0025.txt, test_0026.txt, test_0027.txt, test_0028.txt, test_0029.txt, test_0030.txt, test_0031.txt, test_0032.txt, test_0033.txt, test_0034.txt, test_0035.txt, test_0036.txt, test_0037.txt, test_0038.txt, test_0039.txt, test_0040.txt, test_0041.txt, test_0042.txt, test_0043.txt, test_0044.txt, test_0045.txt, test_0046.txt, test_0047.txt, test_0048.txt, test_0049.txt |
Case Name |
Status |
Exec Time |
Memory |
test_0000.txt |
AC |
4525 ms |
4024 KiB |
test_0001.txt |
AC |
4530 ms |
4116 KiB |
test_0002.txt |
AC |
4553 ms |
4132 KiB |
test_0003.txt |
AC |
4544 ms |
4068 KiB |
test_0004.txt |
AC |
4540 ms |
11460 KiB |
test_0005.txt |
AC |
4542 ms |
4144 KiB |
test_0006.txt |
AC |
4531 ms |
4092 KiB |
test_0007.txt |
AC |
4521 ms |
4036 KiB |
test_0008.txt |
AC |
4535 ms |
4172 KiB |
test_0009.txt |
AC |
4531 ms |
4052 KiB |
test_0010.txt |
AC |
4538 ms |
4080 KiB |
test_0011.txt |
AC |
4529 ms |
4168 KiB |
test_0012.txt |
AC |
4539 ms |
4096 KiB |
test_0013.txt |
AC |
4540 ms |
4132 KiB |
test_0014.txt |
AC |
4524 ms |
4100 KiB |
test_0015.txt |
AC |
4533 ms |
4156 KiB |
test_0016.txt |
AC |
4535 ms |
4068 KiB |
test_0017.txt |
AC |
4530 ms |
4232 KiB |
test_0018.txt |
AC |
4541 ms |
4068 KiB |
test_0019.txt |
AC |
4530 ms |
4248 KiB |
test_0020.txt |
AC |
4536 ms |
4072 KiB |
test_0021.txt |
AC |
4539 ms |
4236 KiB |
test_0022.txt |
AC |
4549 ms |
4184 KiB |
test_0023.txt |
AC |
4528 ms |
4244 KiB |
test_0024.txt |
AC |
4527 ms |
4040 KiB |
test_0025.txt |
AC |
4536 ms |
4060 KiB |
test_0026.txt |
AC |
4547 ms |
4136 KiB |
test_0027.txt |
AC |
4529 ms |
4220 KiB |
test_0028.txt |
AC |
4526 ms |
4140 KiB |
test_0029.txt |
AC |
4529 ms |
4160 KiB |
test_0030.txt |
AC |
4537 ms |
4156 KiB |
test_0031.txt |
AC |
4525 ms |
4220 KiB |
test_0032.txt |
AC |
4544 ms |
4124 KiB |
test_0033.txt |
AC |
4531 ms |
4032 KiB |
test_0034.txt |
AC |
4531 ms |
4116 KiB |
test_0035.txt |
AC |
4539 ms |
4164 KiB |
test_0036.txt |
AC |
4533 ms |
4128 KiB |
test_0037.txt |
AC |
4552 ms |
4044 KiB |
test_0038.txt |
AC |
4523 ms |
3996 KiB |
test_0039.txt |
AC |
4541 ms |
4292 KiB |
test_0040.txt |
AC |
4535 ms |
4036 KiB |
test_0041.txt |
AC |
4541 ms |
4152 KiB |
test_0042.txt |
AC |
4539 ms |
4276 KiB |
test_0043.txt |
AC |
4536 ms |
4064 KiB |
test_0044.txt |
AC |
4527 ms |
4212 KiB |
test_0045.txt |
AC |
4533 ms |
4112 KiB |
test_0046.txt |
AC |
4529 ms |
4220 KiB |
test_0047.txt |
AC |
4531 ms |
4232 KiB |
test_0048.txt |
AC |
4534 ms |
4148 KiB |
test_0049.txt |
AC |
4527 ms |
4192 KiB |