Submission #2090046
Source Code Expand
import std.stdio, std.string, std.conv;
import std.range, std.algorithm, std.array;
import std.random, std.datetime, std.container, std.typecons;
import std.math : abs;
enum {
H = 50, // 盤面の縦幅
W = 50, // 盤面の横幅
K = 2500, // 操作列の長さ
}
int N; // 餌の数
int sr, sc; // 犬の初期位置
char[][] map; // 盤面情報
int[][] esa; // 各cellに何番目の餌があるか(無い場合は-1)
int[] initScore; // 各餌の初期スコア
int[] dec; // 各餌の減少スコア/sec
string ans; // 最終的に出力するコマンド列
int time; // 現在の時刻
void proc() {
// コマンド列の長さがK以上になるまで続ける
int rp = sr, cp = sc;
while (ans.length < K) {
// 現在の位置から最も近くてかつ正の得点を持つ餌へ移動する
// BFSでやる
auto str = BFS(rp, cp);
if (str.empty) break;
ans ~= str;
time += str.length;
}
if (ans.length < K) {
ans ~= repeat('-', K - ans.length.to!int).to!string;
}
ans = ans[0 .. K];
return;
}
immutable(int[]) dr = [1, 0, -1, 0];
immutable(int[]) dc = [0, 1, 0, -1];
string dir = "DRUL";
// 現在の位置(rp, rc)から最も近い正の餌へたどり着くためのコマンド列を返す
string BFS(ref int rp, ref int rc) {
alias Pos = Tuple!(int, "r", int, "c", int, "dist");
auto from = new char[][](H, W);
fillAll(from, 'x');
from[rp][rc] = '-';
auto q = Queue!(Pos)(H*W);
q.insert(Pos(rp, rc, 0));
int lastr = -1, lastc = -1;
while(!q.empty) {
auto v = q.front;
q.removeFront();
foreach (k ; 0 .. 4) {
int nr = v.r + dr[k];
int nc = v.c + dc[k];
if (map[nr][nc] != '#' && from[nr][nc] == 'x') {
int idx = esa[nr][nc];
if (idx == -1) {
from[nr][nc] = dir[k];
q.insert(Pos(nr, nc, v.dist + 1));
}
else if (initScore[idx] - dec[idx] * (time + v.dist + 1) >= 0) {
from[nr][nc] = dir[k];
q.insert(Pos(nr, nc, v.dist + 1));
lastr = nr, lastc = nc;
}
}
}
if (lastr != -1) break;
}
if (lastr == -1) {
return "";
}
rp = lastr;
rc = lastc;
string res;
while (from[lastr][lastc] != '-') {
res ~= from[lastr][lastc];
esa[lastr][lastc] = -1;
final switch (from[lastr][lastc]) {
case 'R':
lastc--;
break;
case 'L':
lastc++;
break;
case 'D':
lastr--;
break;
case 'U':
lastr++;
break;
}
}
esa[lastr][lastc] = -1;
res = res.retro.to!(string);
debug {
stderr.writeln("res:", res);
}
return res;
}
void input() {
auto line = readln.split.to!(int[]);
sr = line[3] - 1, sc = line[4] - 1;
map = new char[][](H, W);
foreach (i ; 0 .. H) {
map[i] = readln.chomp.to!(char[]);
}
scan(N);
initScore = new int[](N);
dec = new int[](N);
esa = new int[][](H, W);
fillAll(esa, -1);
foreach (i ; 0 .. N) {
int fr, fc, F, D;
scan(fr, fc, F, D);
fr--, fc--;
esa[fr][fc] = i;
initScore[i] = F;
dec[i] = D;
}
}
void output() {
assert(ans.length == K);
writeln(ans);
}
void main() {
input();
proc();
output();
}
void scan(T...)(ref T args) {
import std.stdio : readln;
import std.algorithm : splitter;
import std.conv : to;
import std.range.primitives;
auto line = readln().splitter();
foreach (ref arg; args) {
arg = line.front.to!(typeof(arg));
line.popFront();
}
assert(line.empty);
}
void fillAll(R, T)(ref R arr, T value) {
static if (is(typeof(arr[] = value))) {
arr[] = value;
}
else {
foreach (ref e; arr) {
fillAll(e, value);
}
}
}
struct Queue(T) {
private {
size_t cap, head, tail;
T[] data;
}
this (size_t n) in {
assert(n > 0, "The capacity of a queue must be a positive integer.");
} body {
cap = n + 1;
data = new T[](cap);
}
void clear() {
head = tail = 0;
}
bool empty() {
return head == tail;
}
bool full() {
return head == (tail + 1) % cap;
}
size_t length() {
return head <= tail ? tail - head : cap - head + tail;
}
T front() in {
assert(!empty, "The queue is empty.");
} body {
return data[head];
}
void removeFront() in {
assert(!empty, "The queue is empty.");
} body {
(++head) %= cap;
}
alias popFront = removeFront;
void insertBack(T x) in {
assert(!full, "The queue is full.");
} body {
data[tail++] = x;
tail %= cap;
}
alias insert = insertBack;
T[] array() {
return head <= tail ? data[head .. tail].dup : data[head .. $] ~ data[0 .. tail];
}
string toString() {
import std.format : format;
if (head <= tail) {
return format("[%(%s, %)]", data[head .. tail]);
}
else {
return format("[%(%s, %)", data[head .. $]) ~ format(", %(%s, %)]", data[0 .. tail]);
}
}
}
Submission Info
Submission Time |
|
Task |
B - Food Collector |
User |
nanae |
Language |
D (DMD64 v2.070.1) |
Score |
17843 |
Code Size |
5843 Byte |
Status |
AC |
Exec Time |
9 ms |
Memory |
4988 KB |
Judge Result
Set Name |
test_01 |
test_02 |
test_03 |
test_04 |
test_05 |
test_06 |
test_07 |
test_08 |
test_09 |
test_10 |
Score / Max Score |
1710 / 20000 |
2341 / 20000 |
1823 / 20000 |
1075 / 20000 |
1867 / 20000 |
2233 / 20000 |
1892 / 20000 |
1576 / 20000 |
1153 / 20000 |
2173 / 20000 |
Status |
|
|
|
|
|
|
|
|
|
|
Set Name |
Test Cases |
test_01 |
subtask_01_01.txt |
test_02 |
subtask_01_02.txt |
test_03 |
subtask_01_03.txt |
test_04 |
subtask_01_04.txt |
test_05 |
subtask_01_05.txt |
test_06 |
subtask_01_06.txt |
test_07 |
subtask_01_07.txt |
test_08 |
subtask_01_08.txt |
test_09 |
subtask_01_09.txt |
test_10 |
subtask_01_10.txt |
Case Name |
Status |
Exec Time |
Memory |
subtask_01_01.txt |
AC |
7 ms |
4860 KB |
subtask_01_02.txt |
AC |
9 ms |
4860 KB |
subtask_01_03.txt |
AC |
8 ms |
4860 KB |
subtask_01_04.txt |
AC |
6 ms |
4988 KB |
subtask_01_05.txt |
AC |
8 ms |
4860 KB |
subtask_01_06.txt |
AC |
9 ms |
4860 KB |
subtask_01_07.txt |
AC |
8 ms |
4860 KB |
subtask_01_08.txt |
AC |
8 ms |
4988 KB |
subtask_01_09.txt |
AC |
6 ms |
4988 KB |
subtask_01_10.txt |
AC |
8 ms |
4860 KB |