Submission #1174165
Source Code Expand
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <sys/time.h>
#define REP(i,n) for(int i=0; i<(int)(n); i++)
#include <cstdio>
inline int getInt(){ int s; scanf("%d", &s); return s; }
#include <set>
const int _dx[] = {0,1,0,-1,0};
const int _dy[] = {-1,0,1,0,0};
#define IN(x,s,g) ((x) >= (s) && (x) < (g))
#define ISIN(x,y,w,h) (IN((x),0,(w)) && IN((y),0,(h)))
using namespace std;
int h, w, k, t;
int x[450];
int y[450];
int xd[450];
int yd[450];
int phase = 0;
char buff[512];
#define MOVE(x, y, xx, yy) for(int _d = 0, xx, yy; xx = (x) + _dx[_d], yy = (y) + _dy[_d], _d < 4 && ISIN(xx, yy, w, h); _d++)
int board[30][30];
vector<int> randomV(int n){
vector<int> r(n);
REP(i,n) r[i] = i;
random_shuffle(r.begin(), r.end());
return r;
}
class Matching{
typedef vector<vector<int> > G;
vector<bool> visited;
const G &g; //g[i][j] = k <==> i is connected to k
int n; //number of node
int m; //number of left node
bool augment(int left) {
if (left < 0)
return true;
if (visited[left])
return false;
visited[left] = true;
REP(i, g[left].size()) {
int right = g[left][i];
if (augment(matching[right])) {
matching[right] = left;
return true;
}
}
return false;
}
public:
vector<int> matching;
explicit Matching(const G &graph, int mm)
: g(graph), m(mm){
n = graph.size();
}
int solve() {
int matches = 0;
matching = vector<int>(n,-1);
visited = vector<bool>(n);
REP(left, m) {
visited.assign(n, false);
if (augment(left))
matches++;
}
return matches;
}
};
string solve0(int turn){
int cnt = 0;
vector<int> decided(k, 0);
vector<vector<set<int> > > cand(h, vector<set<int> >(w));
memset(board, -1, sizeof(board));
REP(i,k) board[y[i]][x[i]] = i;
vector<vector<int> > g(k + h * w);
auto index = [&](int x, int y){ return k + y * w + x; };
REP(i,k){
if((x[i] + y[i]) % 2 == turn % 2){
const int j = index(x[i], y[i]);
g[i].push_back(j);
g[j].push_back(i);
}else{
const vector<int> d = randomV(4);
REP(dd,4){
const int xx = x[i] + _dx[d[dd]];
const int yy = y[i] + _dy[d[dd]];
if(!ISIN(xx, yy, w, h)) continue;
if(board[yy][xx] == -1){
const int j = index(xx, yy);
g[i].push_back(j);
g[j].push_back(i);
}
}
}
}
REP(i,k) buff[i] = '-';
Matching matching(g, k);
const int t = matching.solve();
if(t == k) phase = 1;
REP(i,h) REP(j,w){
const int o = matching.matching[k + i * w + j];
if(o != -1){
const int xx = x[o];
const int yy = y[o];
if(yy == i){
if(xx + 1 == j){
buff[o] = 'R';
}else if(xx - 1 == j){
buff[o] = 'L';
}
}else if(xx == j){
if(yy + 1 == i){
buff[o] = 'D';
}else if(yy - 1 == i){
buff[o] = 'U';
}
}
x[o] = j;
y[o] = i;
}
}
return buff;
}
double calc(int turn){
const double pt = 10 + turn * 0.01;
double pd = 20;
REP(i,k){
pd += std::abs(x[i] - xd[i]) + std::abs(y[i] - yd[i]);
}
return 1e7 / (pd * pt);
}
void debug(){
memset(board, -1, sizeof(board));
REP(i,k) board[y[i]][x[i]] = i;
REP(i,h) {
REP(j,w){
if(board[i][j] == -1) putchar('.');
else putchar('+');
}
puts("");
}
}
struct Edge{
int cap; // capacity
int to;
int rev; // reverse edge id
Edge(){}
Edge(int c, int t, int r) :
cap(c), to(t), rev(r){}
};
struct CostEdge : public Edge{
int cost;
CostEdge() : Edge() {}
CostEdge(int c, int t, int cs, int r) :
Edge(c, t, r), cost(cs){}
};
template<class E> // Edge type
class Graph{
public:
typedef std::vector<std::vector<E> > G;
private:
G g;
public:
Graph(int n) : g(G(n)) {}
void addEdge(int from, int to, int cap){
g[from].push_back(E(cap, to, g[to].size()));
g[to].push_back(E(0, from, g[from].size() - 1));
}
void addEdge(int from, int to, int cap, int cost){
g[from].push_back(E(cap, to, cost, g[to].size()));
g[to].push_back(E(0, from, -cost, g[from].size() - 1));
}
G &getRowGraph(){
return g;
}
};
#include <queue>
#include <climits>
template<class E>
int minCostFlow(Graph<E> &graph, int s, int t, int f){
typedef pair<int, int> P;
typename Graph<E>::G &g = graph.getRowGraph();
int n = g.size();
int res = 0;
vector<int> h(n, 0);
vector<int> prevv(n);
vector<int> preve(n);
const int inf = 10000000;
while(f > 0){
priority_queue<P, vector<P>, greater<P> > que;
vector<int> dist(n, inf);
dist[s] = 0;
que.push(P(0, s));
while(!que.empty()){
P p = que.top(); que.pop();
int v = p.second;
if(dist[v] < p.first) continue;
for(int i = 0; i < (int)g[v].size(); i++){
E &e = g[v][i];
if(e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]){
dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
prevv[e.to] = v;
preve[e.to] = i;
que.push(P(dist[e.to], e.to));
}
}
}
if(dist[t] == inf){
return -1;
}
for(int v = 0; v < n; v++) h[v] += dist[v];
int d = f;
for(int v = t; v != s; v = prevv[v]){
d = min(d, g[prevv[v]][preve[v]].cap);
}
f -= d;
res += d * h[t];
for(int v = t; v != s; v = prevv[v]){
E &e = g[prevv[v]][preve[v]];
e.cap -= d;
g[v][e.rev].cap += d;
}
}
return res;
}
string solve1(int turn){
Graph<CostEdge> g(2 + k + h * w);
const int src = k + h * w;
const int dst = k + h * w + 1;
auto index = [&](int x, int y){ return k + y * w + x; };
REP(i,k){
const vector<int> d = randomV(4);
REP(dd,4){
const int xx = x[i] + _dx[d[dd]];
const int yy = y[i] + _dy[d[dd]];
if(!ISIN(xx, yy, w, h)) continue;
const int j = index(xx, yy);
const int cost = std::abs(yy - yd[i]) + std::abs(xx - xd[i]);
g.addEdge(i, j, 1, cost);
}
}
REP(i,k){
g.addEdge(src, i, 1, 0);
}
REP(i,h) REP(j,w){
g.addEdge(index(j, i), dst, 1, 0);
}
const int cost = minCostFlow(g, src, dst, k);
// printf("cost: %d\n", cost);
const auto gg = g.getRowGraph();
REP(i,k){
buff[i] = '-';
REP(j,gg[i].size()){
if(gg[i][j].cap == 0){
const int t = gg[i][j].to;
const int xx = (t - k) % w;
const int yy = (t - k) / w;
if(yy == y[i]){
if(x[i] + 1 == xx){
buff[i] = 'R';
}else if(x[i] - 1 == xx){
buff[i] = 'L';
}
}else if(xx == x[i]){
if(y[i] + 1 == yy){
buff[i] = 'D';
}else if(y[i] - 1 == yy){
buff[i] = 'U';
}
}
x[i] = xx;
y[i] = yy;
break;
}
}
}
return buff;
}
string solve2(int turn){
REP(i,k){
buff[i] = '-';
if(x[i] == xd[i]){
if(y[i] + 1 == yd[i]) buff[i] = 'D';
else if(y[i] - 1 == yd[i]) buff[i] = 'U';
}else if(y[i] == yd[i]){
if(x[i] + 1 == xd[i]) buff[i] = 'R';
else if(x[i] - 1 == xd[i]) buff[i] = 'L';
}
}
return buff;
}
double cur(){
struct timeval tm;
gettimeofday(&tm, NULL);
return tm.tv_sec + tm.tv_usec * 1e-6;
}
int main(){
const int h = ::h = getInt();
const int w = ::w = getInt();
const int k = ::k = getInt();
const int t = ::t = getInt();
vector<string> anss;
vector<double> scores;
REP(i,k){
y[i] = getInt() - 1;
x[i] = getInt() - 1;
yd[i] = getInt() - 1;
xd[i] = getInt() - 1;
}
const double start = cur();
for(int i = 0; i < t && cur() - start < 3.7; i++){
if(phase == 0){
const string s = solve0(i);
const double score = calc(i + 1);
anss.push_back(s);
scores.push_back(score);
}else if(phase == 1){
const string s = solve1(i);
bool ok = true;
int cost = 0;
REP(i,k){
const int t = std::abs(x[i] - xd[i]) + std::abs(y[i] - yd[i]);
cost += t;
if(t > 1) ok = false;
}
if(ok) phase = 2;
const double score = calc(i + 1);
anss.push_back(s);
scores.push_back(score);
}else{
const string s = solve2(i);
const double score = calc(i + 1);
anss.push_back(s);
scores.push_back(score);
}
}
const int tn = max_element(scores.begin(), scores.end()) - scores.begin();
printf("%d\n", tn);
REP(i,tn) puts(anss[i].c_str());
return 0;
}
Submission Info
Submission Time |
|
Task |
B - 日本橋大渋滞 |
User |
yukim |
Language |
C++14 (Clang 3.8.0) |
Score |
13502 |
Code Size |
8968 Byte |
Status |
AC |
Exec Time |
3769 ms |
Memory |
1288 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 |
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 |
450 / 50000 |
518 / 50000 |
508 / 50000 |
531 / 50000 |
484 / 50000 |
456 / 50000 |
415 / 50000 |
495 / 50000 |
431 / 50000 |
393 / 50000 |
474 / 50000 |
435 / 50000 |
473 / 50000 |
458 / 50000 |
412 / 50000 |
508 / 50000 |
430 / 50000 |
414 / 50000 |
394 / 50000 |
437 / 50000 |
440 / 50000 |
394 / 50000 |
428 / 50000 |
361 / 50000 |
451 / 50000 |
454 / 50000 |
529 / 50000 |
407 / 50000 |
424 / 50000 |
498 / 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 |
3727 ms |
1288 KB |
subtask_01_02.txt |
AC |
3742 ms |
684 KB |
subtask_01_03.txt |
AC |
3707 ms |
688 KB |
subtask_01_04.txt |
AC |
3705 ms |
688 KB |
subtask_01_05.txt |
AC |
3764 ms |
696 KB |
subtask_01_06.txt |
AC |
3720 ms |
688 KB |
subtask_01_07.txt |
AC |
3761 ms |
692 KB |
subtask_01_08.txt |
AC |
3725 ms |
696 KB |
subtask_01_09.txt |
AC |
3760 ms |
696 KB |
subtask_01_10.txt |
AC |
3751 ms |
704 KB |
subtask_01_11.txt |
AC |
3753 ms |
688 KB |
subtask_01_12.txt |
AC |
3757 ms |
696 KB |
subtask_01_13.txt |
AC |
3761 ms |
696 KB |
subtask_01_14.txt |
AC |
3710 ms |
692 KB |
subtask_01_15.txt |
AC |
3753 ms |
692 KB |
subtask_01_16.txt |
AC |
3717 ms |
692 KB |
subtask_01_17.txt |
AC |
3755 ms |
692 KB |
subtask_01_18.txt |
AC |
3740 ms |
692 KB |
subtask_01_19.txt |
AC |
3711 ms |
704 KB |
subtask_01_20.txt |
AC |
3734 ms |
688 KB |
subtask_01_21.txt |
AC |
3765 ms |
692 KB |
subtask_01_22.txt |
AC |
3769 ms |
692 KB |
subtask_01_23.txt |
AC |
3746 ms |
688 KB |
subtask_01_24.txt |
AC |
3736 ms |
692 KB |
subtask_01_25.txt |
AC |
3733 ms |
700 KB |
subtask_01_26.txt |
AC |
3765 ms |
696 KB |
subtask_01_27.txt |
AC |
3728 ms |
700 KB |
subtask_01_28.txt |
AC |
3733 ms |
692 KB |
subtask_01_29.txt |
AC |
3714 ms |
684 KB |
subtask_01_30.txt |
AC |
3719 ms |
692 KB |