Submission #8259447
Source Code Expand
// 単純解
#include <bits/stdc++.h>
#include <utility>
#define INF 1e9
using namespace std;
#define REPR(i, n) for(int i=(n); i >= 0; --i)
#define FOR(i, m, n) for(int i = (m); i < (n); ++i)
#define REP(i, n) for(int i=0, i##_len=(n); i<i##_len; ++i)
#define ALL(a) (a).begin(),(a).end()
template<class T>
bool chmin(T &a, const T &b) {
if (b < a) {
a = b;
return true;
}
return false;
}
template<class T>
bool chmax(T &a, const T &b) {
if (a < b) {
a = b;
return true;
}
return false;
}
template<class T>
void print(const T &value) {
std::cout << value << std::endl;
}
template<class T>
void errorPrint(const T &value) {
std::cerr << value << std::endl;
}
typedef long long ll;
string string_from_vector(const std::vector<std::string> &v) {
string s;
for (const auto &piece : v) s += piece;
return s;
}
class Map;
const double LIMIT_TIME_SECOND = 3.0;
enum Direction {
UP,
LEFT,
DOWN,
RIGHT,
NONE
};
double time(clock_t st) {
return (static_cast<double>(clock() - st) / CLOCKS_PER_SEC);
}
template<typename T>
void remove(std::vector<T> &vector, unsigned int index) {
vector.erase(vector.begin() + index);
}
enum State {
RANDOM,
HANDMADE,
MANHATTAN,
BLANK
};
class Block {
public:
pair<int, int> location;
explicit Block(pair<int, int> loc) {
location = loc;
}
};
class Robot {
int mapSize;
pair<int, int> location;
Direction direction = NONE;
set<pair<int, int>> visited;
// 一動作
void move(const Map &);
// 端処理など
void goTo(const pair<int, int> &, const Map &);
public:
bool simulate(const Map &m, pair<int, int> goal) {
auto bef = location;
do {
bef = location;
move(m);
if (location == goal) return true;
} while (bef == location);
return false;
}
explicit Robot(pair<int, int> l, char d, int size) {
location = l;
if (d == 'U') direction = UP;
else if (d == 'D') direction = DOWN;
else if (d == 'L') direction = LEFT;
else if (d == 'R') direction = RIGHT;
else throw logic_error("無効な方向がrobotの初期化に入力されました。");
mapSize = size;
visited.insert(location);
}
};
class DirectionIndicator {
public:
pair<int, int> location;
Direction direction;
explicit DirectionIndicator(pair<int, int> l, char d) {
if (d == 'U') direction = UP;
else if (d == 'D') direction = DOWN;
else if (d == 'L') direction = LEFT;
else if (d == 'R') direction = RIGHT;
else throw logic_error("無効な方向がdirection indicatorの初期化に入力されました。");
location = l;
}
explicit DirectionIndicator(pair<int, int> l, Direction d) {
direction = d;
location = l;
}
};
string getStringFromDirection(const Direction &d) {
switch (d) {
case UP:
return "U";
case DOWN:
return "D";
case RIGHT:
return "R";
case LEFT:
return "L";
case NONE:
throw logic_error("その方向は存在しません。");
}
}
class DirectionIndicators {
DirectionIndicators createManhattanIndicates(int mapSize, pair<int, int> goal);
public:
set<pair<int, int>> locations;
vector<DirectionIndicator> directionIndicators;
explicit DirectionIndicators(const vector<DirectionIndicator> &directionIndis) {
directionIndicators = directionIndis;
for (const auto &di:directionIndicators) {
locations.insert(di.location);
}
}
void update(DirectionIndicator p) {
locations.insert(p.location);
REP(i, directionIndicators.size()) {
if (directionIndicators[i].location == p.location) directionIndicators[i].direction = p.direction;
}
}
explicit DirectionIndicators(int mapSize = 40) {
random_device rnd;
int count = rnd() % 1000;
vector<DirectionIndicator> ds(count, DirectionIndicator(make_pair(0, 0), UP));
int nowCount = 0;
while (nowCount != count) {
int befCount = locations.size();
pair<int, int> l = make_pair(rnd() % 40, rnd() % 40);
locations.insert(l);
// 座標被りの場合は無視して再実行
if (befCount == locations.size()) continue;
ds[nowCount] = DirectionIndicator(l, static_cast<Direction>(rnd() % 4));
nowCount++;
}
directionIndicators = ds;
}
explicit DirectionIndicators(State s, pair<int, int> goal, int mapSize = 40) {
DirectionIndicators d;
switch (s) {
case RANDOM:
d = DirectionIndicators(mapSize);
this->locations = d.locations;
this->directionIndicators = d.directionIndicators;
break;
case MANHATTAN:
d = createManhattanIndicates(mapSize, goal);
this->locations = d.locations;
this->directionIndicators = d.directionIndicators;
break;
}
// マンハッタン距離を使用して方向を一意に定める、
}
void print() {
cout << directionIndicators.size() << endl;
for (const auto &di: directionIndicators) {
cout << di.location.first << " " << di.location.second << " " << getStringFromDirection(di.direction)
<< endl;
}
}
};
class Map {
private:
vector<vector<string>> _backup_map;
// for backup
vector<Block> blocks;
vector<vector<string>> create(int size, const vector<Block> &, const pair<int, int> &goal);
public:
vector<vector<string>> map;
void inject(const DirectionIndicators &di) {
// 一応
reset();
for (const auto &d:di.directionIndicators) {
if (map[d.location.first][d.location.second] == "#") throw logic_error("inject実行前にvalidateしてください");
else if (map[d.location.first][d.location.second] == "G") throw logic_error("GOALへの案内は不可");
map[d.location.first][d.location.second] = getStringFromDirection(d.direction);
}
}
DirectionIndicators rand(DirectionIndicators &di, int dd = 3) {
random_device rnd;
vector<DirectionIndicator> r;
pair<int, int> v[8] = {make_pair(-1, -1), make_pair(-1, 0), make_pair(-1, 1), make_pair(0, -1), make_pair(0, 1),
make_pair(1, -1), make_pair(1, 0), make_pair(1, 1)};
for (const auto &d:di.directionIndicators) {
if (map[d.location.first][d.location.second] == "#") throw logic_error("rand実行前にvalidateしてください");
else if (map[d.location.first][d.location.second] == "G") throw logic_error("GOALへの案内は不可");
auto p = make_pair(rnd() % (dd + 1), rnd() % (dd + 1));
REP(i, 8) {
auto y = d.location.first + v[i].first;
auto x = d.location.second + v[i].second;
if (y >= 40) y -= 40;
else if (y < 0) y += 40;
if (x >= 40) x -= 40;
else if (x < 0) x += 40;
if (map[y][x] == "#") {
REP(k, 8) {
if (map[y + v[i].first][x + v[i].second] == "L") {
map[y + v[i].first][x + v[i].second] = "R";
di.update(DirectionIndicator(make_pair(y + v[i].first, x + v[i].second), 'R'));
} else if (map[y + v[i].first][x + v[i].second] == "R") {
map[y + v[i].first][x + v[i].second] = "L";
di.update(DirectionIndicator(make_pair(y + v[i].first, x + v[i].second), 'L'));
} else if (map[y + v[i].first][x + v[i].second] == "U") {
map[y + v[i].first][x + v[i].second] = "D";
di.update(DirectionIndicator(make_pair(y + v[i].first, x + v[i].second), 'D'));
} else if (map[y + v[i].first][x + v[i].second] == "D") {
map[y + v[i].first][x + v[i].second] = "U";
di.update(DirectionIndicator(make_pair(y + v[i].first, x + v[i].second), 'U'));
}
}
}
}
map[d.location.first][d.location.second] = getStringFromDirection(d.direction);
}
}
// 案内に#は含まれていないか
DirectionIndicators validateDirectionIndicator(const DirectionIndicators &di) {
vector<DirectionIndicator> r;
for (const auto &d:di.directionIndicators) {
if (map[d.location.first][d.location.second] == "#") continue;
r.emplace_back(make_pair(d.location.first, d.location.second), d.direction);
}
return DirectionIndicators(r);
}
explicit Map(int size, const vector<Block> &bs, const pair<int, int> &goal) {
map = create(size, bs, goal);
}
explicit Map(int size, const vector<Block> &bs, const DirectionIndicators &vdi, const pair<int, int> &goal) {
map = create(size, bs, goal);
inject(vdi);
}
void reset() {
map = _backup_map;
}
void print() {
for (const vector<string> &v: this->map) {
cerr << string_from_vector(v) << endl;
}
}
};
// 引数: 行先
void Robot::goTo(const pair<int, int> &p, const Map &m) {
if (p.first < 0) location.first = mapSize + p.first;
if (p.second < 0) location.second = mapSize + p.second;
if (p.first >= mapSize) location.first = p.first - mapSize;
if (p.second >= mapSize) location.second = p.second - mapSize;
visited.insert(location);
}
void Robot::move(const Map &m) {
if (m.map[location.first][location.second] == "U") direction = UP;
else if (m.map[location.first][location.second] == "D") direction = DOWN;
else if (m.map[location.first][location.second] == "L") direction = LEFT;
else if (m.map[location.first][location.second] == "R") direction = RIGHT;
else if (m.map[location.first][location.second] == "#") throw logic_error("岩の中にいる");
switch (direction) {
case UP:
goTo(make_pair(location.first - 1, location.second), m);
break;
case DOWN:
goTo(make_pair(location.first + 1, location.second), m);
break;
case RIGHT:
goTo(make_pair(location.first, location.second + 1), m);
break;
case LEFT:
goTo(make_pair(location.first, location.second - 1), m);
break;
case NONE:
throw logic_error("ロボットの向きがわかりません");
}
}
vector<vector<string>> Map::create(int size, const vector<Block> &bs, const pair<int, int> &goal) {
vector<vector<string>> m(size, vector<string>(size));
REP(i, size) {
REP(j, size) m[i][j] = ".";
}
for (const auto &block:bs) m[block.location.first][block.location.second] = "#";
m[goal.first][goal.second] = "G";
blocks = bs;
_backup_map = m;
return m;
}
DirectionIndicators
DirectionIndicators::createManhattanIndicates(int mapSize, pair<int, int> goal) {
vector<DirectionIndicator> direcI;
int overY = -1;
int overX = -1;
if (goal.first > int(mapSize / 2)) overY = goal.first - int(mapSize / 2);
else if (goal.first <= int(mapSize / 2)) overY = goal.first + int(mapSize / 2);
if (goal.second >= int(mapSize / 2)) overX = goal.second - int(mapSize / 2);
else if (goal.second < int(mapSize / 2)) overX = goal.second + int(mapSize / 2);
if (overX != -1) {
if (overX < int(mapSize / 2)) {
REP(x, overX) {
auto dd = DirectionIndicator(make_pair(goal.first, x), 'L');
direcI.push_back(dd);
}
FOR(x, overX, goal.second) {
auto dd = DirectionIndicator(make_pair(goal.first, x), 'R');
direcI.push_back(dd);
}
FOR(x, goal.second + 1, mapSize) {
auto dd = DirectionIndicator(make_pair(goal.first, x), 'L');
direcI.push_back(dd);
}
} else if (overX >= int(mapSize / 2)) {
REP(x, goal.second) {
auto dd = DirectionIndicator(make_pair(goal.first, x), 'R');
direcI.push_back(dd);
}
FOR(x, goal.second + 1, overX) {
auto dd = DirectionIndicator(make_pair(goal.first, x), 'L');
direcI.push_back(dd);
}
FOR(x, overX, mapSize) {
auto dd = DirectionIndicator(make_pair(goal.first, x), 'R');
direcI.push_back(dd);
}
} else throw logic_error("overXの値がおかしい");
} else {
REP(x, int(mapSize/2)) {
auto dd = DirectionIndicator(make_pair(goal.first, x), 'R');
direcI.push_back(dd);
}
FOR(x, int(mapSize/2)+1, mapSize) {
auto dd = DirectionIndicator(make_pair(goal.first, x), 'L');
direcI.push_back(dd);
}
}
if (overY != -1) {
if (overY < int(mapSize / 2)) {
REP(y, overY) {
REP(x, mapSize) {
auto dd = DirectionIndicator(make_pair(y, x), 'U');
direcI.push_back(dd);
}
}
FOR(y, overY, goal.first) {
REP(x, mapSize) {
auto dd = DirectionIndicator(make_pair(y, x), 'D');
direcI.push_back(dd);
}
}
FOR(y, goal.first + 1, mapSize) {
REP(x, mapSize) {
auto dd = DirectionIndicator(make_pair(y, x), 'U');
direcI.push_back(dd);
}
}
} else if (overY >= int(mapSize / 2)) {
REP(y, goal.first) {
REP(x, mapSize) {
auto dd = DirectionIndicator(make_pair(y, x), 'D');
direcI.push_back(dd);
}
}
FOR(y, goal.first + 1, overY) {
REP(x, mapSize) {
auto dd = DirectionIndicator(make_pair(y, x), 'U');
direcI.push_back(dd);
}
}
FOR(y, overY, mapSize) {
REP(x, mapSize) {
auto dd = DirectionIndicator(make_pair(y, x), 'D');
direcI.push_back(dd);
}
}
} else throw logic_error("overXの値がおかしい");
}
return DirectionIndicators(direcI);
}
int main() {
auto startTime = clock();
int N, M, B;
cin >> N >> M >> B;
int gx, gy;
cin >> gy >> gx;
auto goal = make_pair(gy, gx);
vector<Robot> rbts(M, Robot(make_pair(0, 0), 'U', N));
REP(i, M) {
int ry, rx;
char d;
cin >> ry >> rx >> d;
rbts[i] = Robot(make_pair(ry, rx), d, N);
}
vector<Block> bks(B, Block(make_pair(0, 0)));
REP(i, B) {
int by, bx;
cin >> by >> bx;
bks[i] = Block(make_pair(by, bx));
}
auto di = DirectionIndicators(MANHATTAN, goal, N);
auto m = Map(N, bks, goal);
di = m.validateDirectionIndicator(di);
di.print();
cerr << time(startTime) << endl;
return 0;
}
Submission Info
| Submission Time |
|
| Task |
A - ロボットの誘導 |
| User |
reud |
| Language |
C++14 (GCC 5.4.1) |
| Score |
-216360 |
| Code Size |
16109 Byte |
| Status |
AC |
| Exec Time |
5 ms |
| Memory |
512 KiB |
Judge Result
| Set Name |
Sample1 |
Sample2 |
Sample3 |
All |
| Score / Max Score |
-10643 / 100000 |
4362 / 100000 |
-9675 / 100000 |
-200404 / 4700000 |
| Status |
|
|
|
|
| Set Name |
Test Cases |
| Sample1 |
example_01.txt |
| Sample2 |
example_02.txt |
| Sample3 |
example_03.txt |
| All |
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 |
| example_01.txt |
AC |
5 ms |
512 KiB |
| example_02.txt |
AC |
5 ms |
512 KiB |
| example_03.txt |
AC |
5 ms |
512 KiB |
| subtask_01_04.txt |
AC |
5 ms |
512 KiB |
| subtask_01_05.txt |
AC |
5 ms |
512 KiB |
| subtask_01_06.txt |
AC |
5 ms |
512 KiB |
| subtask_01_07.txt |
AC |
5 ms |
512 KiB |
| subtask_01_08.txt |
AC |
5 ms |
512 KiB |
| subtask_01_09.txt |
AC |
5 ms |
512 KiB |
| subtask_01_10.txt |
AC |
5 ms |
512 KiB |
| subtask_01_11.txt |
AC |
5 ms |
512 KiB |
| subtask_01_12.txt |
AC |
5 ms |
512 KiB |
| subtask_01_13.txt |
AC |
5 ms |
512 KiB |
| subtask_01_14.txt |
AC |
5 ms |
512 KiB |
| subtask_01_15.txt |
AC |
5 ms |
512 KiB |
| subtask_01_16.txt |
AC |
5 ms |
512 KiB |
| subtask_01_17.txt |
AC |
5 ms |
512 KiB |
| subtask_01_18.txt |
AC |
5 ms |
512 KiB |
| subtask_01_19.txt |
AC |
5 ms |
512 KiB |
| subtask_01_20.txt |
AC |
5 ms |
512 KiB |
| subtask_01_21.txt |
AC |
5 ms |
512 KiB |
| subtask_01_22.txt |
AC |
5 ms |
512 KiB |
| subtask_01_23.txt |
AC |
5 ms |
512 KiB |
| subtask_01_24.txt |
AC |
5 ms |
512 KiB |
| subtask_01_25.txt |
AC |
5 ms |
512 KiB |
| subtask_01_26.txt |
AC |
5 ms |
512 KiB |
| subtask_01_27.txt |
AC |
5 ms |
512 KiB |
| subtask_01_28.txt |
AC |
5 ms |
512 KiB |
| subtask_01_29.txt |
AC |
5 ms |
512 KiB |
| subtask_01_30.txt |
AC |
5 ms |
512 KiB |
| subtask_01_31.txt |
AC |
5 ms |
512 KiB |
| subtask_01_32.txt |
AC |
5 ms |
512 KiB |
| subtask_01_33.txt |
AC |
5 ms |
512 KiB |
| subtask_01_34.txt |
AC |
5 ms |
512 KiB |
| subtask_01_35.txt |
AC |
5 ms |
512 KiB |
| subtask_01_36.txt |
AC |
5 ms |
512 KiB |
| subtask_01_37.txt |
AC |
5 ms |
512 KiB |
| subtask_01_38.txt |
AC |
5 ms |
512 KiB |
| subtask_01_39.txt |
AC |
5 ms |
512 KiB |
| subtask_01_40.txt |
AC |
5 ms |
512 KiB |
| subtask_01_41.txt |
AC |
5 ms |
512 KiB |
| subtask_01_42.txt |
AC |
5 ms |
512 KiB |
| subtask_01_43.txt |
AC |
5 ms |
512 KiB |
| subtask_01_44.txt |
AC |
5 ms |
512 KiB |
| subtask_01_45.txt |
AC |
5 ms |
512 KiB |
| subtask_01_46.txt |
AC |
5 ms |
512 KiB |
| subtask_01_47.txt |
AC |
5 ms |
512 KiB |
| subtask_01_48.txt |
AC |
5 ms |
512 KiB |
| subtask_01_49.txt |
AC |
5 ms |
512 KiB |
| subtask_01_50.txt |
AC |
5 ms |
512 KiB |