Skip to content

Commit 021e850

Browse files
committed
Quora Programming Challenge 2021 Division 2 (Rank: 28)
1 parent dbe82b3 commit 021e850

File tree

6 files changed

+620
-0
lines changed

6 files changed

+620
-0
lines changed

quora/2021-2/connect4.cpp

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include <bits/stdc++.h>
2+
3+
using namespace std;
4+
5+
int mat[8][8], h[8];
6+
7+
int main() {
8+
memset(mat, -1, sizeof mat);
9+
for (int turn = 1; turn <= 42; ++turn) {
10+
int c;
11+
scanf("%d", &c);
12+
--c;
13+
int now = turn & 1;
14+
int r = 0;
15+
while (mat[r][c] != -1) ++r;
16+
mat[r][c] = now;
17+
bool found = false;
18+
for (int i = 0; i < 6; ++i) {
19+
for (int j = 0; j < 7; ++j) {
20+
if (mat[i][j] == -1) continue;
21+
if (i + 4 <= 6) {
22+
bool ok = true;
23+
for (int k = 0; k < 4 && ok; ++k) {
24+
ok &= mat[i+k][j] == mat[i][j];
25+
}
26+
found |= ok;
27+
}
28+
if (j + 4 <= 7) {
29+
bool ok = true;
30+
for (int k = 0; k < 4 && ok; ++k) {
31+
ok &= mat[i][j+k] == mat[i][j];
32+
}
33+
found |= ok;
34+
}
35+
if (i + 4 <= 6 && j + 4 <= 7) {
36+
bool ok = true;
37+
for (int k = 0; k < 4 && ok; ++k) {
38+
ok &= mat[i+k][j+k] == mat[i][j];
39+
}
40+
found |= ok;
41+
}
42+
if (i + 4 <= 6 && j-3 >= 0) {
43+
bool ok = true;
44+
for (int k = 0; k < 4 && ok; ++k) {
45+
ok &= mat[i+k][j-k] == mat[i][j];
46+
}
47+
found |= ok;
48+
}
49+
}
50+
}
51+
if (found) {
52+
printf("%s %d\n", now ? "RED" : "YELLOW", turn);
53+
return 0;
54+
}
55+
}
56+
puts("DRAW");
57+
return 0;
58+
}

quora/2021-2/crawlers.cpp

+226
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
#include <bits/stdc++.h>
2+
3+
using namespace std;
4+
5+
const int N = 1e6 + 6, INF = 1e8 + 7;
6+
7+
struct Edge {
8+
int from, to, cap, flow, index;
9+
Edge(int from, int to, int cap, int flow, int index) :
10+
from(from), to(to), cap(cap), flow(flow), index(index) {}
11+
};
12+
13+
struct Dinic {
14+
int N;
15+
vector<vector<Edge> > G;
16+
vector<Edge *> dad;
17+
vector<int> Q;
18+
19+
Dinic(int N) : N(N), G(N), dad(N), Q(N) {}
20+
21+
void AddEdge(int from, int to, int cap) {
22+
G[from].push_back(Edge(from, to, cap, 0, G[to].size()));
23+
if (from == to) G[from].back().index++;
24+
G[to].push_back(Edge(to, from, 0, 0, G[from].size() - 1));
25+
}
26+
27+
long long BlockingFlow(int s, int t) {
28+
fill(dad.begin(), dad.end(), (Edge *) NULL);
29+
dad[s] = &G[0][0] - 1;
30+
31+
int head = 0, tail = 0;
32+
Q[tail++] = s;
33+
while (head < tail) {
34+
int x = Q[head++];
35+
for (int i = 0; i < G[x].size(); i++) {
36+
Edge &e = G[x][i];
37+
if (!dad[e.to] && e.cap - e.flow > 0) {
38+
dad[e.to] = &G[x][i];
39+
Q[tail++] = e.to;
40+
}
41+
}
42+
}
43+
if (!dad[t]) return 0;
44+
45+
long long totflow = 0;
46+
for (int i = 0; i < G[t].size(); i++) {
47+
Edge *start = &G[G[t][i].to][G[t][i].index];
48+
int amt = INF;
49+
for (Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
50+
if (!e) { amt = 0; break; }
51+
amt = min(amt, e->cap - e->flow);
52+
}
53+
if (amt == 0) continue;
54+
for (Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
55+
e->flow += amt;
56+
G[e->to][e->index].flow -= amt;
57+
}
58+
totflow += amt;
59+
}
60+
return totflow;
61+
}
62+
63+
int find(int v) {
64+
for (auto & e : G[v]) {
65+
if (e.flow > 0) {
66+
--e.flow;
67+
if (e.to == N-2) {
68+
return v;
69+
} else {
70+
return find(e.to);
71+
}
72+
}
73+
}
74+
return -1;
75+
}
76+
77+
long long GetMaxFlow(int s, int t) {
78+
long long totflow = 0;
79+
while (long long flow = BlockingFlow(s, t))
80+
totflow += flow;
81+
return totflow;
82+
}
83+
};
84+
85+
vector<int> g[N];
86+
set<int> dag[N];
87+
88+
int elem[N], scc = 0, num[N], low[N], vis[N], tmpt = 0, group[N];
89+
90+
bool starting[N];
91+
92+
vector<int> nodes;
93+
94+
void dfs(int v) {
95+
nodes.push_back(v);
96+
num[v] = low[v] = tmpt++;
97+
vis[v] = true;
98+
for (int u : g[v]) {
99+
if (num[u] == -1) {
100+
dfs(u);
101+
}
102+
if (vis[u]) {
103+
low[v] = min(low[v], low[u]);
104+
}
105+
}
106+
if (num[v] == low[v]) {
107+
elem[scc] = v;
108+
while (true) {
109+
int w = nodes.back();
110+
nodes.pop_back();
111+
group[w] = scc;
112+
vis[w] = false;
113+
if (w == v)
114+
break;
115+
}
116+
++scc;
117+
}
118+
}
119+
120+
int match[N];
121+
122+
int main() {
123+
int n, m;
124+
scanf("%d %d", &n, &m);
125+
for (int i = 0; i < m; ++i) {
126+
int u, v;
127+
scanf("%d %d", &u, &v);
128+
--u, --v;
129+
g[u].push_back(v);
130+
}
131+
memset(num, -1, sizeof num);
132+
for (int i = 0; i < n; ++i) {
133+
if (num[i] == -1) {
134+
dfs(i);
135+
}
136+
}
137+
fill(starting, starting + scc, true);
138+
for (int v = 0; v < n; ++v) {
139+
for (int u : g[v]) {
140+
if (group[u] != group[v]) {
141+
dag[group[v]].insert(group[u]);
142+
starting[group[u]] = false;
143+
}
144+
}
145+
}
146+
Dinic mf(scc + 2);
147+
int source = scc, sink = source + 1;
148+
for (int v = 0; v < scc; ++v) {
149+
if (starting[v])
150+
mf.AddEdge(source, v, 1);
151+
if (dag[v].empty())
152+
mf.AddEdge(v, sink, 1);
153+
for (int u : dag[v]) {
154+
mf.AddEdge(v, u, scc);
155+
}
156+
}
157+
vector<int> bef(scc, -1);
158+
vector<int> aft(scc, -1);
159+
vector<int> din(scc, 0);
160+
for (int v = 0; v < scc; ++v) {
161+
for (int u : dag[v]) {
162+
++din[u];
163+
}
164+
}
165+
vector<int> topo;
166+
iota(bef.begin(), bef.end(), 0);
167+
iota(aft.begin(), aft.end(), 0);
168+
for (int v = 0; v < scc; ++v) {
169+
if (din[v] == 0) {
170+
topo.push_back(v);
171+
}
172+
}
173+
for (int v : topo) {
174+
for (int u : g[v]) {
175+
--din[u];
176+
if (din[u] == 0)
177+
topo.push_back(u);
178+
}
179+
}
180+
for (int v : topo) {
181+
for (int u : dag[v]) {
182+
bef[u] = bef[v];
183+
}
184+
}
185+
for (int i = (int)topo.size()-1; i >= 0; --i) {
186+
int v = topo[i];
187+
for (int u : dag[v]) {
188+
aft[v] = aft[u];
189+
}
190+
}
191+
memset(match, -1, sizeof match);
192+
vector<pair<int, int>> seg;
193+
mf.GetMaxFlow(source, sink);
194+
for (auto & e : mf.G[source]) {
195+
if (e.flow > 0) {
196+
int res = mf.find(e.to);
197+
assert(res != -1);
198+
match[e.to] = res;
199+
match[res] = e.to;
200+
seg.emplace_back(e.to, res);
201+
}
202+
}
203+
for (int i = 0; i < scc; ++i) {
204+
if (dag[i].empty() && match[i] == -1) {
205+
seg.emplace_back(bef[i], i);
206+
} else if (starting[i] && match[i] == -1) {
207+
seg.emplace_back(i, aft[i]);
208+
}
209+
}
210+
sort(seg.begin(), seg.end());
211+
seg.erase(unique(seg.begin(), seg.end()), seg.end());
212+
if (seg.size() == 0) {
213+
puts("0");
214+
return 0;
215+
}
216+
if (seg.size() == 1 && seg[0].first == seg[0].second) {
217+
puts("0");
218+
return 0;
219+
}
220+
printf("%d\n", (int)seg.size());
221+
seg.push_back(seg[0]);
222+
for (int i = 0; i + 1 < (int)seg.size(); ++i) {
223+
printf("%d %d\n", elem[seg[i].second]+1, elem[seg[i+1].first]+1);
224+
}
225+
return 0;
226+
}

quora/2021-2/datacenter.cpp

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#include <bits/stdc++.h>
2+
3+
using namespace std;
4+
5+
vector<long long> score;
6+
7+
template<class T>
8+
struct BIT {
9+
vector<T> sum;
10+
BIT(int _n) : sum(_n+2, 0) {}
11+
void upd(int x, T v) {
12+
for (++x; x < (int)sum.size(); x += x&-x)
13+
sum[x] += v;
14+
}
15+
T get(int x) {
16+
T ret = 0;
17+
for (++x; x; x -= x&-x)
18+
ret += sum[x];
19+
return ret;
20+
}
21+
};
22+
23+
void process(vector<tuple<int, int, int, int>> &events) {
24+
vector<int> allr, allc;
25+
allr.reserve(events.size());
26+
allc.reserve(events.size());
27+
for (auto & e : events) {
28+
int r, c;
29+
tie(r, c, ignore, ignore) = e;
30+
allr.push_back(r);
31+
allc.push_back(c);
32+
}
33+
auto vunique = [&](vector<int> & v) {
34+
sort(v.begin(), v.end());
35+
v.erase(unique(v.begin(), v.end()), v.end());
36+
};
37+
// vunique(allr);
38+
vunique(allc);
39+
BIT<long long> sum(allc.size());
40+
BIT<int> cnt(allc.size());
41+
sort(events.begin(), events.end());
42+
for (auto & e : events) {
43+
int r, c, id, v;
44+
tie(r, c, id, v) = e;
45+
c = lower_bound(allc.begin(), allc.end(), c) - allc.begin();
46+
score[id] += sum.get(c-1) + 1LL * v * cnt.get(c-1);
47+
sum.upd(c, -v);
48+
cnt.upd(c, 1);
49+
}
50+
}
51+
52+
int main() {
53+
int n;
54+
scanf("%d", &n);
55+
score.resize(n);
56+
vector<int> x(n), y(n);
57+
for (int i = 0; i < n; ++i) {
58+
scanf("%d %d", &x[i], &y[i]);
59+
}
60+
vector<tuple<int, int, int, int>> events(n);
61+
for (int i = 0; i < n; ++i) {
62+
int r = -(x[i] + y[i]), c = x[i] - y[i];
63+
events[i] = {r, c, i, -y[i]};
64+
}
65+
process(events);
66+
for (int i = 0; i < n; ++i) {
67+
int r = y[i] - x[i], c = - (x[i] + y[i]);
68+
events[i] = {r, c, i, -x[i]};
69+
}
70+
process(events);
71+
for (int i = 0; i < n; ++i) {
72+
int r = x[i] + y[i], c = y[i] - x[i];
73+
events[i] = {r, c, i, y[i]};
74+
}
75+
process(events);
76+
for (int i = 0; i < n; ++i) {
77+
int r = x[i] - y[i], c = x[i] + y[i];
78+
events[i] = {r, c, i, x[i]};
79+
}
80+
process(events);
81+
printf("%d\n", (int)(min_element(score.begin(), score.end()) - score.begin() + 1));
82+
return 0;
83+
}

0 commit comments

Comments
 (0)