Submission #1358804
Source Code Expand
#pragma GCC optimize ("O3")
#pragma GCC target ("avx")
#include "bits/stdc++.h" // define macro "/D__MAI"
using namespace std;
typedef long long int ll;
#define debugv(v) printf("L%d %s => ",__LINE__,#v);for(auto e:v){cout<<e<<" ";}cout<<endl;
#define debugm(m) printf("L%d %s is..\n",__LINE__,#m);for(auto v:m){for(auto e:v){cout<<e<<" ";}cout<<endl;}
#define debuga(m,w) printf("L%d %s is => ",__LINE__,#m);for(int x=0;x<(w);x++){cout<<(m)[x]<<" ";}cout<<endl;
#define debugaa(m,w,h) printf("L%d %s is..\n",__LINE__,#m);for(int y=0;y<(h);y++){for(int x=0;x<(w);x++){cout<<(m)[x][y]<<" ";}cout<<endl;}
#define debugaar(m,w,h) printf("L%d %s is..\n",__LINE__,#m);for(int y=0;y<(h);y++){for(int x=0;x<(w);x++){cout<<(m)[y][x]<<" ";}cout<<endl;}
#define ALL(v) (v).begin(),(v).end()
#define repeat(l) for(auto cnt=0;cnt<(l);++cnt)
#define iterate(b,e) for(auto cnt=(b);cnt!=(e);++cnt)
#define MD 1000000007ll
#define PI 3.1415926535897932384626433832795
template<typename T1, typename T2>
ostream& operator <<(ostream &o, const pair<T1, T2> p) { o << "(" << p.first << ":" << p.second << ")"; return o; }
#define TIME chrono::system_clock::now()
#define MILLISEC(t) (chrono::duration_cast<chrono::milliseconds>(t).count())
namespace {
std::chrono::system_clock::time_point ttt;
void tic() { ttt = TIME; }
void toc() { fprintf(stderr, "TIME : %lldms\n", MILLISEC(TIME - ttt)); }
std::chrono::system_clock::time_point tle = TIME;
#ifdef __MAI
void safe_tle(int msec) { assert(MILLISEC(TIME - tle) < msec); }
#else
#define safe_tle(k) ;
#endif
}
#ifdef __MAI
#define getchar_unlocked getchar
#define putchar_unlocked putchar
#endif
#ifdef __VSCC
#define getchar_unlocked _getchar_nolock
#define putchar_unlocked _putchar_nolock
#endif
namespace {
#define isvisiablechar(c) (0x21<=(c)&&(c)<=0x7E)
class MaiScanner {
public:
template<typename T>
void input_integer(T& var) {
var = 0;
T sign = 1;
int cc = getchar_unlocked();
for (; cc<'0' || '9'<cc; cc = getchar_unlocked())
if (cc == '-') sign = -1;
for (; '0' <= cc&&cc <= '9'; cc = getchar_unlocked())
var = (var << 3) + (var << 1) + cc - '0';
var = var*sign;
}
inline int c() { return getchar_unlocked(); }
inline MaiScanner& operator>>(int& var) {
input_integer<int>(var);
return *this;
}
inline MaiScanner& operator>>(long long& var) {
input_integer<long long>(var);
return *this;
}
inline MaiScanner& operator>>(string& var) {
int cc = getchar_unlocked();
for (; !isvisiablechar(cc); cc = getchar_unlocked());
for (; isvisiablechar(cc); cc = getchar_unlocked())
var.push_back(cc);
}
};
class MaiPrinter {
int stack_p;
char stack[32];
public:
template<typename T>
void output_integer(T var) {
if (var == 0) {
putchar_unlocked('0');
return;
}
if (var < 0) {
putchar_unlocked('-');
var = -var;
}
stack_p = 0;
while (var) {
stack[stack_p++] = '0' + (var % 10);
var /= 10;
}
while (stack_p)
putchar_unlocked(stack[--stack_p]);
}
inline MaiPrinter& operator<<(char c) {
putchar_unlocked(c);
return *this;
}
inline MaiPrinter& operator<<(int var) {
output_integer<int>(var);
return *this;
}
inline MaiPrinter& operator<<(long long var) {
output_integer<long long>(var);
return *this;
}
inline MaiPrinter& operator<(int var) {
output_integer<int>(var);
putchar_unlocked(' ');
return *this;
}
inline MaiPrinter& operator<(long long var) {
output_integer<long long>(var);
putchar_unlocked(' ');
return *this;
}
inline MaiPrinter& operator<<(const string& str) {
const char* p = str.c_str();
const char* l = p + str.size();
while (p < l) putchar_unlocked(*p++);
return *this;
}
};
}
MaiScanner scanner;
MaiPrinter printer;
random_device noize;
mt19937 mt(noize());
int rand_int(int l, int h) {
uniform_int_distribution<> range(l, h);
return range(mt);
}
class Flow {
public:
size_t n;
struct Arrow {
int from, to;
int left;
int cap;
Arrow(int from = 0, int to = 0, int w = 1) :from(from), to(to), left(w), cap(w) {}
bool operator<(const Arrow& a) const { return (from<a.from) | (to<a.to) | (left<a.left) | (cap<a.cap); }
bool operator==(const Arrow& a) const { return (from == a.from) && (to == a.to) && (left == a.left) && (cap == a.cap); }
};
vector<vector<int>> vertex_to;
vector<vector<int>> vertex_from;
vector<Arrow> arrow;
Flow(int n, int m = 5010) :n(n), vertex_to(n), vertex_from(n) { arrow.reserve(m); }
void connect(int from, int to, int left) {
vertex_to[from].push_back(arrow.size()); // toto
vertex_from[to].push_back(arrow.size()); // fromfrom
arrow.emplace_back(from, to, left);
}
size_t degree(int v) {
return vertex_to[v].size() + vertex_from[v].size();
}
size_t degree_in(int v) {
return vertex_from[v].size();
}
size_t degree_out(int v) {
return vertex_to[v].size();
}
};
int _dinic_path_dfs(Flow& flow, vector<int>& result, vector<int>& flag, const vector<int>& dist, int u, int i_sink, int mini) {
// TODO: 経路再利用
if (i_sink == u) return mini;
if (flag[u]) return -1;
flag[u] = true;
int sumw = 0;
bool term = true;
for (int e : flow.vertex_to[u]) {
Flow::Arrow& a = flow.arrow[e];
if (a.left > 0 && dist[u]>dist[a.to]) {
int w;
if (mini < 0)
w = a.left;
else
w = min(a.left, mini);
w = _dinic_path_dfs(flow, result, flag, dist, a.to, i_sink, w);
if (w == -1) continue;
a.left -= w;
result[a.to] += w;
sumw += w;
mini -= w;
term = false;
flag[u] = false; // TODO: 末尾では?
if (mini == 0) return term ? -1 : sumw;
}
}
for (int e : flow.vertex_from[u]) {
Flow::Arrow& a = flow.arrow[e];
if (a.cap>a.left && dist[u]>dist[a.from]) {
int w;
if (mini < 0)
w = a.cap - a.left;
else
w = min(a.cap - a.left, mini);
w = _dinic_path_dfs(flow, result, flag, dist, a.from, i_sink, w);
if (w == -1) continue;
a.left += w;
result[a.to] -= w;
sumw += w;
mini -= w;
term = false;
flag[u] = false;
if (mini == 0) return term ? -1 : sumw;
}
}
return term ? -1 : sumw;
}
// flowは書き換えられる.
void dinic(Flow &flow, vector<int>& result, int i_source, int i_sink) {
assert(i_source != i_sink);
result.resize(flow.n);
int distbegin = 0;
vector<int> dist(flow.n);
queue<int> q;
vector<int> flag(flow.n);
for (int distbegin = 0; ; distbegin += flow.n) {
q.emplace(i_sink); // bfsはsinkからsourceへの距離を計算.
dist[i_sink] = distbegin + 1;
while (!q.empty()) {
int v = q.front();
q.pop();
for (int ie : flow.vertex_from[v]) {
const Flow::Arrow& e = flow.arrow[ie];
if (0<e.left && dist[e.from] <= distbegin) {
dist[e.from] = dist[v] + 1;
q.emplace(e.from);
}
}
for (int ie : flow.vertex_to[v]) {
const Flow::Arrow& e = flow.arrow[ie];
if (e.left<e.cap && dist[e.to] <= distbegin) {
dist[e.to] = dist[v] + 1;
q.emplace(e.to);
}
}
}
//debugv(dist);
fill(ALL(flag), false);
if (dist[i_source] <= distbegin) {
break;
}
else {
result[i_source] += _dinic_path_dfs(flow, result, flag, dist, i_source, i_sink, -1);
}
}
}
#define cv_d2i(y,x) ((y)*width+(x))
int height = 30, width = 30, n = 450, t_limit = 10000;
inline bool isscreenout(int y, int x) {
return y < 0 || x < 0 || height <= y || width <= x;
}
inline char actvel2char(int vy, int vx) {
return vx < 0 ? 'L' : vx>0 ? 'R' : vy < 0 ? 'U' : vy>0 ? 'D' : '-';
}
inline void actchar(int &y, int &x, int c) {
if (c == 'L') --x;
else if (c == 'R') ++x;
else if (c == 'U') --y;
else if (c == 'D') ++y;
}
class Car {
public:
int y, x, dy, dx;
Car(int y = 0, int x = 0, int dy = 0, int dx = 0) :y(y), x(x), dy(dy), dx(dx) {}
};
class State {
public:
vector<int> data;
vector<Car> cars;
string acts;
int turn;
State() :data(width*height, -1), cars(n), acts(n, '-') { }
inline int& operator()(int y, int x) {
return data[x + y*width];
}
inline int operator()(int y, int x) const {
return data[x + y*width];
}
inline int& at(int y, int x) {
return data[x + y*width];
}
inline int at(int y, int x) const {
return data[x + y*width];
}
void put(int carid, int y, int x, int dx, int dy) {
at(y, x) = carid;
cars[carid] = Car(y, x, dx, dy);
}
bool action(int carid, int vy, int vx) {
const Car& car = cars[carid];
if (isscreenout(car.y + vy, car.x + vx)) return false;
int& to = at(car.y + vy, car.x + vx);
if (to != -1) return false;
to = -2 - carid;
acts[carid] = actvel2char(vy, vx);
return true;
}
int act_count() const {
int cnt = 0;
for (char c : acts) {
cnt += (c != '-');
}
return cnt;
}
// bool print() const {
// string s;
// bool b = false;
// for (char c : acts) {
// if (b |= (c != '-')) break;
// }
// if (!b) return false;
// printer << acts << '\n';
// return true;
// }
void eprint() const {
printf("---\n");
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
printf("%4d", at(y, x));
}
printf("\n");
}
}
State next_state() const {
State new_state = *this;
new_state.turn += 1;
for (int i = 0; i < n; ++i) {
Car &car = new_state.cars[i];
new_state.at(car.y, car.x) = -1;
actchar(car.y, car.x, new_state.acts[i]);
new_state.at(car.y, car.x) = i;
}
fill(ALL(new_state.acts), '-');
return new_state;
}
int score() const{
}
};
State first_state;
list<State> result;
void solve_greedy(int count, const State& first) {
State state = first;
repeat(t_limit) {
for (int i = 0; i < n; ++i) {
Car &car = state.cars[i];
int uy = car.dy - car.y;
int ux = car.dx - car.x;
bool pr = rand_int(0, 1);
if (uy != 0 && (ux == 0 || pr)) {
if (uy > 0) pr = state.action(i, 1, 0);
else pr = state.action(i, -1, 0);
}
if (ux != 0 && (uy == 0 || !pr)) {
if (ux > 0) state.action(i, 0, 1);
else state.action(i, 0, -1);
}
}
//state.eprint();
if (state.act_count() < 10) break;
result.push_back(state);
state = state.next_state();
}
}
void solve_zigzag1() {
vector<int> r_flow;
vector<int> used(height*width, -1);
vector<int> edgelabel(20000);
State state = first_state;
repeat(40) {
Flow flow(height*width + 2);
const int tail = height*width;
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
if ((y + x) % 2 == state.turn % 2) continue;
int carid = state(y, x);
if (carid == -1)continue;
Car &car = state.cars[carid];
int uy = car.dy - car.y;
int ux = car.dx - car.x;
bool pr = rand_int(0, 1);
flow.connect(tail, cv_d2i(y, x), 1);
if (uy < 0)
if (!isscreenout(y - 1, x) && state(y - 1, x) == -1) {
edgelabel[flow.arrow.size()] = 'U';
flow.connect(cv_d2i(y, x), cv_d2i(y - 1, x), 1);
if (used[cv_d2i(y - 1, x)] < cnt) {
used[cv_d2i(y - 1, x)] = cnt;
flow.connect(cv_d2i(y - 1, x), tail + 1, 1);
}
}
if (uy > 0)
if (!isscreenout(y + 1, x) && state(y + 1, x) == -1) {
edgelabel[flow.arrow.size()] = 'D';
flow.connect(cv_d2i(y, x), cv_d2i(y + 1, x), 1);
if (used[cv_d2i(y + 1, x)] < cnt) {
used[cv_d2i(y + 1, x)] = cnt;
flow.connect(cv_d2i(y + 1, x), tail + 1, 1);
}
}
if (ux < 0)
if (!isscreenout(y, x - 1) && state(y, x - 1) == -1) {
edgelabel[flow.arrow.size()] = 'L';
flow.connect(cv_d2i(y, x), cv_d2i(y, x - 1), 1);
if (used[cv_d2i(y, x - 1)] < cnt) {
used[cv_d2i(y, x - 1)] = cnt;
flow.connect(cv_d2i(y, x - 1), tail + 1, 1);
}
}
if (ux > 0)
if (!isscreenout(y, x + 1) && state(y, x + 1) == -1) {
edgelabel[flow.arrow.size()] = 'R';
flow.connect(cv_d2i(y, x), cv_d2i(y, x + 1), 1);
if (used[cv_d2i(y, x + 1)] < cnt) {
used[cv_d2i(y, x + 1)] = cnt;
flow.connect(cv_d2i(y, x + 1), tail + 1, 1);
}
}
if (rand_int(0, 2) == 0) {
if (uy >= 0)
if (!isscreenout(y - 1, x) && state(y - 1, x) == -1) {
edgelabel[flow.arrow.size()] = 'U';
flow.connect(cv_d2i(y, x), cv_d2i(y - 1, x), 1);
if (used[cv_d2i(y - 1, x)] < cnt) {
used[cv_d2i(y - 1, x)] = cnt;
flow.connect(cv_d2i(y - 1, x), tail + 1, 1);
}
}
if (uy <= 0)
if (!isscreenout(y + 1, x) && state(y + 1, x) == -1) {
edgelabel[flow.arrow.size()] = 'D';
flow.connect(cv_d2i(y, x), cv_d2i(y + 1, x), 1);
if (used[cv_d2i(y + 1, x)] < cnt) {
used[cv_d2i(y + 1, x)] = cnt;
flow.connect(cv_d2i(y + 1, x), tail + 1, 1);
}
}
if (ux >= 0)
if (!isscreenout(y, x - 1) && state(y, x - 1) == -1) {
edgelabel[flow.arrow.size()] = 'L';
flow.connect(cv_d2i(y, x), cv_d2i(y, x - 1), 1);
if (used[cv_d2i(y, x - 1)] < cnt) {
used[cv_d2i(y, x - 1)] = cnt;
flow.connect(cv_d2i(y, x - 1), tail + 1, 1);
}
}
if (ux <= 0)
if (!isscreenout(y, x + 1) && state(y, x + 1) == -1) {
edgelabel[flow.arrow.size()] = 'R';
flow.connect(cv_d2i(y, x), cv_d2i(y, x + 1), 1);
if (used[cv_d2i(y, x + 1)] < cnt) {
used[cv_d2i(y, x + 1)] = cnt;
flow.connect(cv_d2i(y, x + 1), tail + 1, 1);
}
}
}
}
}
dinic(flow, r_flow, tail, tail + 1);
for (int ai : flow.vertex_to[tail]) {
int z = flow.arrow[ai].to;
int x = z%width;
int y = z/width;
for (int aii : flow.vertex_to[z]) {
if (flow.arrow[aii].left == 0) {
state.acts[state.data[z]] = edgelabel[aii];
break;
}
}
}
result.push_back(state);
state = state.next_state();
}
solve_greedy(5, state);
}
int main(int argc, char** argv) {
scanner >> height >> width >> n >> t_limit;
first_state.turn = 1;
repeat(n) {
int a, b, c, d;
scanner >> a >> b >> c >> d;
first_state.put(cnt, --a, --b, --c, --d);
}
// solve_greedy();
solve_zigzag1();
printer << (int)result.size() << '\n';
for (State& s : result) {
printer << s.acts << '\n';
}
return 0;
}
Submission Info
Submission Time
2017-06-18 14:55:45+0900
Task
B - 日本橋大渋滞
User
m_buyoh
Language
C++14 (GCC 5.4.1)
Score
5813
Code Size
18302 Byte
Status
AC
Exec Time
12 ms
Memory
1024 KB
Compile Error
./Main.cpp: In function ‘void {anonymous}::toc()’:
./Main.cpp:26:73: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 3 has type ‘std::chrono::duration<long int, std::ratio<1l, 1000l> >::rep {aka long int}’ [-Wformat=]
void toc() { fprintf(stderr, "TIME : %lldms\n", MILLISEC(TIME - ttt)); }
^
Judge Result
Set Name
test_01
test_02
test_03
test_04
test_05
test_06
test_07
test_08
test_09
test_10
test_11
test_12
test_13
test_14
test_15
test_16
test_17
test_18
test_19
test_20
test_21
test_22
test_23
test_24
test_25
test_26
test_27
test_28
test_29
test_30
Score / Max Score
204 / 50000
221 / 50000
210 / 50000
205 / 50000
213 / 50000
208 / 50000
192 / 50000
206 / 50000
187 / 50000
199 / 50000
198 / 50000
177 / 50000
185 / 50000
205 / 50000
178 / 50000
201 / 50000
177 / 50000
188 / 50000
177 / 50000
192 / 50000
202 / 50000
184 / 50000
187 / 50000
183 / 50000
188 / 50000
195 / 50000
200 / 50000
174 / 50000
191 / 50000
186 / 50000
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
test_11
subtask_01_11.txt
test_12
subtask_01_12.txt
test_13
subtask_01_13.txt
test_14
subtask_01_14.txt
test_15
subtask_01_15.txt
test_16
subtask_01_16.txt
test_17
subtask_01_17.txt
test_18
subtask_01_18.txt
test_19
subtask_01_19.txt
test_20
subtask_01_20.txt
test_21
subtask_01_21.txt
test_22
subtask_01_22.txt
test_23
subtask_01_23.txt
test_24
subtask_01_24.txt
test_25
subtask_01_25.txt
test_26
subtask_01_26.txt
test_27
subtask_01_27.txt
test_28
subtask_01_28.txt
test_29
subtask_01_29.txt
test_30
subtask_01_30.txt
Case Name
Status
Exec Time
Memory
subtask_01_01.txt
AC
11 ms
1024 KB
subtask_01_02.txt
AC
12 ms
1024 KB
subtask_01_03.txt
AC
11 ms
1024 KB
subtask_01_04.txt
AC
11 ms
1024 KB
subtask_01_05.txt
AC
11 ms
1024 KB
subtask_01_06.txt
AC
11 ms
1024 KB
subtask_01_07.txt
AC
10 ms
1024 KB
subtask_01_08.txt
AC
11 ms
1024 KB
subtask_01_09.txt
AC
11 ms
1024 KB
subtask_01_10.txt
AC
11 ms
1024 KB
subtask_01_11.txt
AC
11 ms
1024 KB
subtask_01_12.txt
AC
10 ms
1024 KB
subtask_01_13.txt
AC
10 ms
1024 KB
subtask_01_14.txt
AC
11 ms
1024 KB
subtask_01_15.txt
AC
10 ms
1024 KB
subtask_01_16.txt
AC
11 ms
1024 KB
subtask_01_17.txt
AC
10 ms
1024 KB
subtask_01_18.txt
AC
10 ms
1024 KB
subtask_01_19.txt
AC
10 ms
1024 KB
subtask_01_20.txt
AC
11 ms
1024 KB
subtask_01_21.txt
AC
10 ms
1024 KB
subtask_01_22.txt
AC
11 ms
1024 KB
subtask_01_23.txt
AC
10 ms
1024 KB
subtask_01_24.txt
AC
10 ms
1024 KB
subtask_01_25.txt
AC
11 ms
1024 KB
subtask_01_26.txt
AC
11 ms
1024 KB
subtask_01_27.txt
AC
11 ms
1024 KB
subtask_01_28.txt
AC
10 ms
1024 KB
subtask_01_29.txt
AC
11 ms
1024 KB
subtask_01_30.txt
AC
11 ms
1024 KB