QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#92048 | #4515. Triangles | KHIN | 50 ✓ | 1231ms | 3720kb | C++17 | 12.1kb | 2023-03-30 09:44:48 | 2023-03-30 09:44:52 |
Judging History
answer
# include <cstdlib>
# include <tuple>
# include <type_traits>
# include <cassert>
# include <vector>
# include <algorithm>
# include <numeric>
# include <cstdio>
# include <iostream>
# include <istream>
# include <ostream>
namespace khin {
using namespace std;
namespace main {
inline namespace source {
template <typename T, enable_if_t<is_signed_v<T>, int> = 0>
int sgn(T const value) { return (value > 0) - (value < 0); }
}
namespace a { void main(); }
namespace b { void main(); }
namespace c { void main(); }
namespace d { void main(); }
namespace e { void main(); }
}
}
int main() { khin::main::e::main(); }
namespace khin::main::e {
namespace test_case {
struct vector {
long x, y;
constexpr vector() : x(), y() {}
explicit constexpr vector(long const x, long const y) : x(x), y(y) {}
constexpr vector operator+() const { return vector(+x, +y); }
constexpr vector operator-() const { return vector(-x, -y); }
constexpr friend vector operator+(vector const u, vector const v)
{ return vector(u.x + v.x, u.y + v.y); }
constexpr friend vector operator-(vector const u, vector const v)
{ return vector(u.x - v.x, u.y - v.y); }
constexpr friend long operator*(vector const u, vector const v)
{ return u.x * v.y - u.y * v.x; }
} typedef point;
constexpr uint n_max(3'000);
uint n; point p[n_max + 1]; std::vector<uint> s, t;
std::vector<tuple<uint, uint, uint>> ans;
void main(ushort const x) {
cin >> n;
for (uint i(1); i <= n; ++i) cin >> p[i].x >> p[i].y;
s.resize(n), iota(s.begin(), s.end(), 1u);
while (s.size() >= 3) {
uint a, b, c; decltype(s)::iterator it;
auto const cmp0 = [] (uint const i, uint const j)
{ return make_pair(p[i].x, p[i].y) < make_pair(p[j].x, p[j].y); };
auto const cmp1 = [&a] (uint const i, uint const j) {
vector const u(p[i] - p[a]), v(p[j] - p[a]);
if (u * v) return u * v > 0;
else return abs(u.x) + abs(u.y) < abs(v.x) + abs(v.y);
};
auto const cmp2 = [&b] (uint const i, uint const j) {
vector const u(p[i] - p[b]), v(p[j] - p[b]);
if (u * v) return u * v < 0;
else return abs(u.x) + abs(u.y) < abs(v.x) + abs(v.y);
};
a = *(it = min_element(s.begin(), s.end(), cmp0)), s.erase(it);
b = *(it = min_element(s.begin(), s.end(), cmp1)), s.erase(it);
c = *(it = min_element(s.begin(), s.end(), cmp2)), s.erase(it);
if ((p[a] - p[b]) * (p[b] - p[c])) ans.emplace_back(a, b, c);
else { s.push_back(a), s.push_back(b), s.push_back(c); break; }
}
while (s.size() % 3) s.pop_back();
/* fprintf(stderr, "%s %u (%zu)\n", __func__, __LINE__, ans.size()); */
if (!s.empty()) {
/*
fprintf(stderr, "%s %u ", __func__, __LINE__);
fprintf(stderr, "(%zu) ", ans.size());
fprintf(stderr, "(%zu %zu)\n", s.size(), t.size());
*/
while (2 * t.size() < s.size() && !ans.empty()) {
auto const [a, b, c](ans.back()); ans.pop_back();
((p[a] - p[s[0]]) * (p[a] - p[s[1]]) ? t : s).push_back(a);
((p[b] - p[s[0]]) * (p[b] - p[s[1]]) ? t : s).push_back(b);
((p[c] - p[s[0]]) * (p[c] - p[s[1]]) ? t : s).push_back(c);
}
/*
fprintf(stderr, "%s %u ", __func__, __LINE__);
fprintf(stderr, "(%zu) ", ans.size());
fprintf(stderr, "(%zu %zu)\n", s.size(), t.size());
*/
while (s.size() > 2 * t.size()) s.pop_back();
/*
fprintf(stderr, "%s %u ", __func__, __LINE__);
fprintf(stderr, "(%zu) ", ans.size());
fprintf(stderr, "(%zu %zu)\n", s.size(), t.size());
*/
assert(2 * t.size() == s.size() || 2 * t.size() == s.size() + 3);
/*
fprintf(stderr, "%s %u ", __func__, __LINE__);
fprintf(stderr, "(%zu) ", ans.size());
fprintf(stderr, "(%zu %zu)\n", s.size(), t.size());
*/
if (s.empty() && !t.empty())
ans.emplace_back(t[0], t[1], t[2]), t.clear();
[] {
auto const comp = [] (uint const i, uint const j)
{ return make_pair(p[i].x, p[i].y) < make_pair(p[j].x, p[j].y); };
sort(s.begin(), s.end(), comp);
} ();
if (!s.empty()) {
vector const d(p[s[1]] - p[s[0]]);
for (uint const i : s) assert(!((p[i] - p[s.back()]) * d));
for (uint const i : t) assert( ((p[i] - p[s.back()]) * d));
while (assert(s.empty() == t.empty()), !s.empty()) {
assert(2 * t.size() == s.size() || 2 * t.size() == s.size() + 3);
if (2 * t.size() == s.size()) {
uint const a(s.back()); s.pop_back();
uint const b(s.back()); s.pop_back();
auto const comp = [&b, d] (uint const i, uint const j) {
vector const u(p[i] - p[b]); assert(u * d);
vector const v(p[j] - p[b]); assert(v * d);
if (sgn(u * d) != sgn(v * d)) return sgn(u * d) < sgn(v * d);
else if (u * v) return sgn(u * d) * (u * v) < 0;
else return abs(u.x) + abs(u.y) < abs(v.x) + abs(v.y);
};
auto const it(min_element(t.begin(), t.end(), comp));
uint const c(*it); t.erase(it);
assert((p[a] - p[b]) * (p[b] - p[c]));
ans.emplace_back(a, b, c);
continue;
}
if (s.size() == 1) {
/* fprintf(stderr, "case %s %u\n", __func__, __LINE__); */
assert(t.size() == 2);
ans.emplace_back(s[0], t[0], t[1]);
s.clear(), t.clear();
continue;
}
uint pos(0), neg(0);
for (uint const i : t) switch (sgn((p[i] - p[s.back()]) * d)) {
case +1: ++pos; break;
case -1: ++neg; break;
default: assert(false);
}
if (pos && pos == min(pos, neg)) {
[d] {
uint const a(s.back()); s.pop_back();
uint const b(s.back()); s.pop_back();
auto const comp = [&b, d] (uint const i, uint const j) {
vector const u(p[i] - p[b]); assert(u * d);
vector const v(p[j] - p[b]); assert(v * d);
if (sgn(u * d) != sgn(v * d)) return u * d > v * d;
else if (u * v) return sgn(u * d) * (u * v) < 0;
else return abs(u.x) + abs(u.y) < abs(v.x) + abs(v.y);
};
auto const it(min_element(t.begin(), t.end(), comp));
uint const c(*it); t.erase(it);
assert((p[a] - p[b]) * (p[b] - p[c]));
ans.emplace_back(a, b, c);
} ();
continue;
}
if (neg && neg == min(pos, neg)) {
[d] {
uint const a(s.back()); s.pop_back();
uint const b(s.back()); s.pop_back();
auto const comp = [&b, d] (uint const i, uint const j) {
vector const u(p[i] - p[b]); assert(u * d);
vector const v(p[j] - p[b]); assert(v * d);
if (sgn(u * d) != sgn(v * d)) return u * d < v * d;
else if (u * v) return sgn(u * d) * (u * v) < 0;
else return abs(u.x) + abs(u.y) < abs(v.x) + abs(v.y);
};
auto const it(min_element(t.begin(), t.end(), comp));
uint const c(*it); t.erase(it);
assert((p[a] - p[b]) * (p[b] - p[c]));
ans.emplace_back(a, b, c);
} ();
continue;
}
if (pos && neg) {
uint const a(s.back()); s.pop_back();
auto const cmp0 = [&a, d] (uint const i, uint const j) {
vector const u(p[i] - p[a]); assert(u * d);
vector const v(p[j] - p[a]); assert(v * d);
if (sgn(u * d) != sgn(v * d)) return sgn(u * d) > sgn(v * d);
else if (u * v) return sgn(u * d) * (u * v) < 0;
else return abs(u.x) + abs(u.y) < abs(v.x) + abs(v.y);
};
auto const cmp1 = [&a, d] (uint const i, uint const j) {
vector const u(p[i] - p[a]); assert(u * d);
vector const v(p[j] - p[a]); assert(v * d);
if (sgn(u * d) != sgn(v * d)) return sgn(u * d) < sgn(v * d);
else if (u * v) return sgn(u * d) * (u * v) < 0;
else return abs(u.x) + abs(u.y) < abs(v.x) + abs(v.y);
};
decltype(t)::iterator it;
uint const b(*(it = min_element(t.begin(), t.end(), cmp0)));
t.erase(it);
uint const c(*(it = min_element(t.begin(), t.end(), cmp1)));
t.erase(it);
ans.emplace_back(a, b, c);
assert((p[a] - p[b]) * (p[b] - p[c]));
continue;
}
if (s.size() > 3) {
uint const a(s.back()); s.pop_back();
uint const b(s.back()); s.pop_back();
auto const comp = [&b, d] (uint const i, uint const j) {
vector const u(p[i] - p[b]); assert(u * d);
vector const v(p[j] - p[b]); assert(v * d);
if (u * v) return sgn(u * d) * (u * v) < 0;
else return abs(u.x) + abs(u.y) < abs(v.x) + abs(v.y);
};
auto const it(min_element(t.begin(), t.end(), comp));
uint const c(*it); t.erase(it);
ans.emplace_back(a, b, c);
continue;
}
assert(s.size() == 3), assert(t.size() == 3);
auto const chk0 = [d] {
auto const comp = [d] (uint const i, uint const j) {
vector const u(p[i] - p[s[0]]); assert(u * d);
vector const v(p[j] - p[s[0]]); assert(v * d);
return sgn(u * d) * (u * v) > 0;
};
sort(t.begin(), t.end(), comp);
return comp(t[0], t[1]);
};
auto const chk1 = [d] {
auto const comp = [d] (uint const i, uint const j) {
vector const u(p[i] - p[s[2]]); assert(u * d);
vector const v(p[j] - p[s[2]]); assert(v * d);
return sgn(u * d) * (u * v) < 0;
};
sort(t.begin(), t.end(), comp);
return comp(t[0], t[1]);
};
if (chk0()) {
/* fprintf(stderr, "case %s %u\n", __func__, __LINE__); */
ans.emplace_back(s[0], t[0], t[1]);
ans.emplace_back(s[1], s[2], t[2]);
s.clear(), t.clear();
continue;
}
if (chk1()) {
/* fprintf(stderr, "case %s %u\n", __func__, __LINE__); */
ans.emplace_back(s[2], t[0], t[1]);
ans.emplace_back(s[1], s[0], t[2]);
s.clear(), t.clear();
continue;
}
/* fprintf(stderr, "case %s %u\n", __func__, __LINE__); */
auto const comp = [d] (uint const i, uint const j) {
vector const u(p[i] - p[s[0]]); assert(u * d);
vector const v(p[j] - p[s[0]]); assert(v * d);
if (u * v) return sgn(u * d) * (u * v) > 0;
else return abs(u.x) + abs(u.y) < abs(v.x) + abs(v.y);
};
sort(t.begin(), t.end(), comp);
ans.emplace_back(s[0], s[2], t[1]);
ans.emplace_back(s[1], t[0], t[2]);
s.clear(), t.clear();
continue;
}
}
}
assert(s.empty()), assert(t.empty());
printf("Case #%hu: %zu\n", x, ans.size());
for (auto const [p, q, r] : ans) printf("%u %u %u\n", p, q, r);
ans.clear();
}
}
void main() {
ushort t; cin >> t;
for (ushort i(1); i <= t; ++i) test_case::main(i);
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 8
Accepted
time: 4ms
memory: 3592kb
input:
100 10 220238472 224691753 770968360 1070897 222060078 225731229 213423928 -699125511 571809960 -531790999 -29325160 82281481 523892900 397968241 134123366 175551277 -48116654 71558357 79192162 144205493 6 -800120306 681957950 -800120120 681958048 -800120239 681957972 -800120068 681958102 -800120280...
output:
Case #1: 3 9 4 6 10 5 8 1 2 3 Case #2: 2 1 3 5 6 2 4 Case #3: 4 11 12 7 4 3 8 6 10 9 1 2 5 Case #4: 0 Case #5: 2 2 3 5 1 6 4 Case #6: 3 1 4 7 9 5 2 8 3 6 Case #7: 2 7 6 4 3 1 2 Case #8: 3 2 7 1 10 9 6 3 8 4 Case #9: 4 11 3 9 4 5 2 12 6 10 8 1 7 Case #10: 2 4 5 1 3 6 2 Case #11: 4 11 5 8 9 12 10 3 6 ...
result:
ok (100 test cases)
Test #2:
score: 42
Accepted
time: 1231ms
memory: 3720kb
input:
100 3000 -92089322 -224238223 -92147554 -225776486 -91601000 -225100640 -92024176 -225644144 -90703509 -224917680 -89202055 -225283952 -92681755 -224149407 -92347180 -225441739 -92259568 -225588653 -91979455 -224254694 -92673281 -224244242 -92527577 -224172521 -90804449 -224883170 -92641474 -2249482...
output:
Case #1: 1000 2743 1593 436 169 1759 2938 2812 2792 2457 46 624 2409 2863 424 999 1335 2697 238 311 2919 1095 1332 1523 787 1515 1042 534 1830 2114 1336 2496 916 275 2666 2023 1297 1693 2755 2234 2685 533 589 1087 2993 1182 2173 2386 2184 1185 2878 1958 2232 764 2584 235 1570 2911 747 2850 1713 57 2...
result:
ok (100 test cases)