diff --git a/geo/count_points_in_triangle/checker.cpp b/geo/count_points_in_triangle/checker.cpp new file mode 100644 index 000000000..6a66d5330 --- /dev/null +++ b/geo/count_points_in_triangle/checker.cpp @@ -0,0 +1,62 @@ +// https://github.com/MikeMirzayanov/testlib/blob/master/checkers/wcmp.cpp + +// The MIT License (MIT) + +// Copyright (c) 2015 Mike Mirzayanov + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include "testlib.h" + +using namespace std; + +int main(int argc, char * argv[]) +{ + setName("compare sequences of tokens"); + registerTestlibCmd(argc, argv); + + int n = 0; + string j, p; + + while (!ans.seekEof() && !ouf.seekEof()) + { + n++; + + ans.readWordTo(j); + ouf.readWordTo(p); + + if (j != p) + quitf(_wa, "%d%s words differ - expected: '%s', found: '%s'", n, englishEnding(n).c_str(), compress(j).c_str(), compress(p).c_str()); + } + + if (ans.seekEof() && ouf.seekEof()) + { + if (n == 1) + quitf(_ok, "\"%s\"", compress(j).c_str()); + else + quitf(_ok, "%d tokens", n); + } + else + { + if (ans.seekEof()) + quitf(_wa, "Participant output contains extra tokens"); + else + quitf(_wa, "Unexpected EOF in the participants output"); + } +} diff --git a/geo/count_points_in_triangle/gen/dense.cpp b/geo/count_points_in_triangle/gen/dense.cpp new file mode 100644 index 000000000..ba013b27c --- /dev/null +++ b/geo/count_points_in_triangle/gen/dense.cpp @@ -0,0 +1,35 @@ +#include +#include + +#include "../params.h" +#include "random.h" +using namespace std; + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int n = N_MAX; + int m = M_MAX; + int q = Q_MAX; + printf("%d\n", n); + for (int i=0; i +#include + +#include "../params.h" +#include "random.h" +using namespace std; + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int n = N_MAX; + int m = M_MAX; + int q = Q_MAX; + printf("%d\n", n); + for (int i=0; i +#include + +#include "../params.h" +#include "random.h" +using namespace std; + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int n = N_MAX; + int m = M_MAX; + int q = min(Q_MAX, 4000'0000 / m); + printf("%d\n", n); + for (int i=0; i +#include +#include + +template +struct VecI2 { + Int x, y; + VecI2() : x(0), y(0) {} + VecI2(Int _x, Int _y) : x(_x), y(_y) {} + VecI2 operator+(VecI2 r) const { return VecI2(x+r.x, y+r.y); } + VecI2 operator-(VecI2 r) const { return VecI2(x-r.x, y-r.y); } + VecI2 operator-() const { return VecI2(-x, -y); } + Int2 operator*(VecI2 r) const { return Int2(x) * Int2(r.x) + Int2(y) * Int2(r.y); } + Int2 operator^(VecI2 r) const { return Int2(x) * Int2(r.y) - Int2(y) * Int2(r.x); } + static bool compareYX(VecI2 a, VecI2 b){ return a.y < b.y || (!(b.y < a.y) && a.x < b.x); } + static bool compareXY(VecI2 a, VecI2 b){ return a.x < b.x || (!(b.x < a.x) && a.y < b.y); } +}; + + +using i64 = long long; +using namespace std; +using Vec = VecI2; +#define rep(i,n) for(int i=0; i<(int)(n); i++) + +int main(){ + using nachia::cin; + using nachia::cout; + int N; cin >> N; + vector A(N); + rep(i,N) cin >> A[i].x >> A[i].y; + int M; cin >> M; + vector B(M); + rep(i,M) cin >> B[i].x >> B[i].y; + + auto pointL = vector(N); // bx < Ax + auto pointM = vector(N); // bx = Ax + rep(i,N) rep(j,M) if(A[i].y == B[j].y){ + if(B[j].x < A[i].x) pointL[i]++; + if(B[j].x == A[i].x) pointM[i]++; + } + + auto edgeL = vector>(N, vector(N)); // bx < lerp(Ax, Bx) + auto edgeM = vector>(N, vector(N)); // bx = lerp(Ax, Bx) + rep(a,N) rep(b,N) if(A[a].y < A[b].y){ + rep(i,M) if(A[a].y < B[i].y && B[i].y < A[b].y){ + auto det = (A[a] - A[b]) ^ (B[i] - A[b]); + if(det < 0) edgeL[a][b]++; + if(det == 0) edgeM[a][b]++; + } + } + + int Q; cin >> Q; + rep(qi, Q){ + int a,b,c; cin >> a >> b >> c; + if(Vec::compareYX(A[b], A[a])) swap(a, b); + if(Vec::compareYX(A[c], A[b])) swap(b, c); + if(Vec::compareYX(A[b], A[a])) swap(a, b); + // c ^y + // b | + // a +---> x + + // c + // nega | + // v posi + // a + auto det = (A[a] - A[c]) ^ (A[b] - A[c]); + int ans = 0; + if(det != 0){ + if(A[a].y == A[b].y){ // A[a].x < A[b].x + // c + // a b + ans = edgeL[b][c] - (edgeL[a][c] + edgeM[a][c]); + } else if(A[b].y == A[c].y){ // A[b].x < A[c].x + // b c + // a + ans = edgeL[a][c] - (edgeL[a][b] + edgeM[a][b]); + } else if(det < 0){ + // c + // b + // a + ans += edgeL[a][c]; + ans -= edgeL[b][c] + edgeM[b][c]; + ans -= edgeL[a][b] + edgeM[a][b]; + ans -= pointL[b] + pointM[b]; + } else { + // c + // b + // a + ans += edgeL[a][b]; + ans += edgeL[b][c]; + ans += pointL[b]; + ans -= edgeL[a][c] + edgeM[a][c]; + } + } + cout << ans << '\n'; + } + return 0; +} diff --git a/geo/count_points_in_triangle/sol/fast.cpp b/geo/count_points_in_triangle/sol/fast.cpp new file mode 100644 index 000000000..87c4e7da4 --- /dev/null +++ b/geo/count_points_in_triangle/sol/fast.cpp @@ -0,0 +1,136 @@ +/* + +O( N M log( N M ) + Q ) time solution + +not so fast at N,M = 1000 + +*/ + +#include "fastio.hpp" +#include +#include +#include + +template +struct VecI2 { + Int x, y; + VecI2() : x(0), y(0) {} + VecI2(Int _x, Int _y) : x(_x), y(_y) {} + VecI2 operator+(VecI2 r) const { return VecI2(x+r.x, y+r.y); } + VecI2 operator-(VecI2 r) const { return VecI2(x-r.x, y-r.y); } + VecI2 operator-() const { return VecI2(-x, -y); } + Int2 operator*(VecI2 r) const { return Int2(x) * Int2(r.x) + Int2(y) * Int2(r.y); } + Int2 operator^(VecI2 r) const { return Int2(x) * Int2(r.y) - Int2(y) * Int2(r.x); } + static bool compareYX(VecI2 a, VecI2 b){ return a.y < b.y || (!(b.y < a.y) && a.x < b.x); } + static bool compareXY(VecI2 a, VecI2 b){ return a.x < b.x || (!(b.x < a.x) && a.y < b.y); } +}; + + +using i64 = long long; +using namespace std; +using Vec = VecI2; +#define rep(i,n) for(int i=0; i<(int)(n); i++) + +int main(){ + using nachia::cin; + using nachia::cout; + int N; cin >> N; + vector A(N); + rep(i,N) cin >> A[i].x >> A[i].y; + int M; cin >> M; + vector B(M); + rep(i,M) cin >> B[i].x >> B[i].y; + + auto pointL = vector(N); // bx < Ax + auto pointM = vector(N); // bx = Ax + rep(i,N) rep(j,M) if(A[i].y == B[j].y){ + if(B[j].x < A[i].x) pointL[i]++; + if(B[j].x == A[i].x) pointM[i]++; + } + + auto edgeL = vector>(N, vector(N)); // bx < lerp(Ax, Bx) + auto edgeM = vector>(N, vector(N)); // bx = lerp(Ax, Bx) + rep(a,N){ + struct PointId { int i; int c; Vec v; }; + vector points; + rep(b,N) if(A[a].y < A[b].y) points.push_back({ b, 0, A[b] - A[a] }); + rep(b,M) if(A[a].y < B[b].y) points.push_back({ b, 1, B[b] - A[a] }); + rep(b,N) if(A[a].y < A[b].y) points.push_back({ b, 2, A[b] - A[a] }); + sort(points.begin(), points.end(), [&](const PointId& l, const PointId& r){ + i64 det = l.v ^ r.v; + if(det != 0) return det < 0; + return l.c < r.c; + }); + int qN = points.size(); + vector queryOrd(qN); rep(i,qN) queryOrd[i] = i; + sort(queryOrd.begin(), queryOrd.end(), [&](int l, int r){ + return make_pair(points[l].v.y, points[l].c%2) < make_pair(points[r].v.y, points[r].c%2); + }); + vector BIT(qN); + for(int qi=0; qi 0){ buf += BIT[p-1]; p -= p & -p; } + edgeL[a][points[q].i] = buf; + } else if(points[q].c == 1) { + int p = q+1; + while(p <= qN){ BIT[p-1]++; p += p & -p; } + } else { + int buf = 0; + int p = q+1; + while(p > 0){ buf += BIT[p-1]; p -= p & -p; } + edgeM[a][points[q].i] = buf; + } + } + rep(b,N) edgeM[a][b] -= edgeL[a][b]; + } + + int Q; cin >> Q; + rep(qi, Q){ + int a,b,c; cin >> a >> b >> c; + if(Vec::compareYX(A[b], A[a])) swap(a, b); + if(Vec::compareYX(A[c], A[b])) swap(b, c); + if(Vec::compareYX(A[b], A[a])) swap(a, b); + // c ^y + // b | + // a +---> x + + // c + // nega | + // v posi + // a + auto det = (A[a] - A[c]) ^ (A[b] - A[c]); + int ans = 0; + if(det != 0){ + if(A[a].y == A[b].y){ // A[a].x < A[b].x + // c + // a b + ans = edgeL[b][c] - (edgeL[a][c] + edgeM[a][c]); + } else if(A[b].y == A[c].y){ // A[b].x < A[c].x + // b c + // a + ans = edgeL[a][c] - (edgeL[a][b] + edgeM[a][b]); + } else if(det < 0){ + // c + // b + // a + ans += edgeL[a][c]; + ans -= edgeL[b][c] + edgeM[b][c]; + ans -= edgeL[a][b] + edgeM[a][b]; + ans -= pointL[b] + pointM[b]; + } else { + // c + // b + // a + ans += edgeL[a][b]; + ans += edgeL[b][c]; + ans += pointL[b]; + ans -= edgeL[a][c] + edgeM[a][c]; + } + } + cout << ans << '\n'; + } + return 0; +} diff --git a/geo/count_points_in_triangle/sol/fastio.hpp b/geo/count_points_in_triangle/sol/fastio.hpp new file mode 100644 index 000000000..d0981a5bb --- /dev/null +++ b/geo/count_points_in_triangle/sol/fastio.hpp @@ -0,0 +1,208 @@ +#pragma once +#include +#include +#include +#include + +namespace nachia{ + +struct CInStream{ +private: + static const unsigned int INPUT_BUF_SIZE = 1 << 17; + unsigned int p = INPUT_BUF_SIZE; + static char Q[INPUT_BUF_SIZE]; +public: + using MyType = CInStream; + char seekChar(){ + if(p == INPUT_BUF_SIZE){ + size_t len = fread(Q, 1, INPUT_BUF_SIZE, stdin); + if(len != INPUT_BUF_SIZE) Q[len] = '\0'; + p = 0; + } + return Q[p]; + } + void skipSpace(){ while(isspace(seekChar())) p++; } +private: + template + T nextUInt(){ + if constexpr (sp) skipSpace(); + T buf = 0; + while(true){ + char tmp = seekChar(); + if('9' < tmp || tmp < '0') break; + buf = buf * 10 + (tmp - '0'); + p++; + } + return buf; + } +public: + uint32_t nextU32(){ return nextUInt(); } + int32_t nextI32(){ + skipSpace(); + if(seekChar() == '-'){ + p++; return (int32_t)(-nextUInt()); + } + return (int32_t)nextUInt(); + } + uint64_t nextU64(){ return nextUInt();} + int64_t nextI64(){ + skipSpace(); + if(seekChar() == '-'){ + p++; return (int64_t)(-nextUInt()); + } + return (int64_t)nextUInt(); + } + template + T nextInt(){ + skipSpace(); + if(seekChar() == '-'){ + p++; + return - nextUInt(); + } + return nextUInt(); + } + char nextChar(){ skipSpace(); char buf = seekChar(); p++; return buf; } + std::string nextToken(){ + skipSpace(); + std::string buf; + while(true){ + char ch = seekChar(); + if(isspace(ch) || ch == '\0') break; + buf.push_back(ch); + p++; + } + return buf; + } + MyType& operator>>(unsigned int& dest){ dest = nextU32(); return *this; } + MyType& operator>>(int& dest){ dest = nextI32(); return *this; } + MyType& operator>>(unsigned long& dest){ dest = nextU64(); return *this; } + MyType& operator>>(long& dest){ dest = nextI64(); return *this; } + MyType& operator>>(unsigned long long& dest){ dest = nextU64(); return *this; } + MyType& operator>>(long long& dest){ dest = nextI64(); return *this; } + MyType& operator>>(std::string& dest){ dest = nextToken(); return *this; } + MyType& operator>>(char& dest){ dest = nextChar(); return *this; } +} cin; + +struct FastOutputTable{ + char LZ[1000][4] = {}; + char NLZ[1000][4] = {}; + constexpr FastOutputTable(){ + using u32 = uint_fast32_t; + for(u32 d=0; d<1000; d++){ + LZ[d][0] = ('0' + d / 100 % 10); + LZ[d][1] = ('0' + d / 10 % 10); + LZ[d][2] = ('0' + d / 1 % 10); + LZ[d][3] = '\0'; + } + for(u32 d=0; d<1000; d++){ + u32 i = 0; + if(d >= 100) NLZ[d][i++] = ('0' + d / 100 % 10); + if(d >= 10) NLZ[d][i++] = ('0' + d / 10 % 10); + if(d >= 1) NLZ[d][i++] = ('0' + d / 1 % 10); + NLZ[d][i++] = '\0'; + } + } +}; + +struct COutStream{ +private: + using u32 = uint32_t; + using u64 = uint64_t; + using MyType = COutStream; + static const u32 OUTPUT_BUF_SIZE = 1 << 17; + static char Q[OUTPUT_BUF_SIZE]; + static constexpr FastOutputTable TB = FastOutputTable(); + u32 p = 0; + static constexpr u32 P10(u32 d){ return d ? P10(d-1)*10 : 1; } + static constexpr u64 P10L(u32 d){ return d ? P10L(d-1)*10 : 1; } + template static void Fil(T& m, U& l, U x){ m = l/x; l -= m*x; } + void next_dig9(u32 x){ + u32 y; + Fil(y, x, P10(6)); + nextCstr(TB.LZ[y]); + Fil(y, x, P10(3)); + nextCstr(TB.LZ[y]); nextCstr(TB.LZ[x]); + } +public: + void nextChar(char c){ + Q[p++] = c; + if(p == OUTPUT_BUF_SIZE){ fwrite(Q, p, 1, stdout); p = 0; } + } + void nextEoln(){ nextChar('\n'); } + void nextCstr(const char* s){ while(*s) nextChar(*(s++)); } + void nextU32(uint32_t x){ + u32 y = 0; + if(x >= P10(9)){ + Fil(y, x, P10(9)); + nextCstr(TB.NLZ[y]); next_dig9(x); + } + else if(x >= P10(6)){ + Fil(y, x, P10(6)); + nextCstr(TB.NLZ[y]); + Fil(y, x, P10(3)); + nextCstr(TB.LZ[y]); nextCstr(TB.LZ[x]); + } + else if(x >= P10(3)){ + Fil(y, x, P10(3)); + nextCstr(TB.NLZ[y]); nextCstr(TB.LZ[x]); + } + else if(x >= 1) nextCstr(TB.NLZ[x]); + else nextChar('0'); + } + void nextI32(int32_t x){ + if(x >= 0) nextU32(x); + else{ nextChar('-'); nextU32((u32)-x); } + } + void nextU64(uint64_t x){ + u32 y = 0; + if(x >= P10L(18)){ + Fil(y, x, P10L(18)); + nextU32(y); + Fil(y, x, P10L(9)); + next_dig9(y); next_dig9(x); + } + else if(x >= P10L(9)){ + Fil(y, x, P10L(9)); + nextU32(y); next_dig9(x); + } + else nextU32(x); + } + void nextI64(int64_t x){ + if(x >= 0) nextU64(x); + else{ nextChar('-'); nextU64((u64)-x); } + } + template + void nextInt(T x){ + if(x < 0){ nextChar('-'); x = -x; } + if(!(0 < x)){ nextChar('0'); return; } + std::string buf; + while(0 < x){ + buf.push_back('0' + (int)(x % 10)); + x /= 10; + } + for(int i=(int)buf.size()-1; i>=0; i--){ + nextChar(buf[i]); + } + } + void writeToFile(bool flush = false){ + fwrite(Q, p, 1, stdout); + if(flush) fflush(stdout); + p = 0; + } + COutStream(){ Q[0] = 0; } + ~COutStream(){ writeToFile(); } + MyType& operator<<(unsigned int tg){ nextU32(tg); return *this; } + MyType& operator<<(unsigned long tg){ nextU64(tg); return *this; } + MyType& operator<<(unsigned long long tg){ nextU64(tg); return *this; } + MyType& operator<<(int tg){ nextI32(tg); return *this; } + MyType& operator<<(long tg){ nextI64(tg); return *this; } + MyType& operator<<(long long tg){ nextI64(tg); return *this; } + MyType& operator<<(const std::string& tg){ nextCstr(tg.c_str()); return *this; } + MyType& operator<<(const char* tg){ nextCstr(tg); return *this; } + MyType& operator<<(char tg){ nextChar(tg); return *this; } +} cout; + +char CInStream::Q[INPUT_BUF_SIZE]; +char COutStream::Q[OUTPUT_BUF_SIZE]; + +} // namespace nachia diff --git a/geo/count_points_in_triangle/sol/naive.cpp b/geo/count_points_in_triangle/sol/naive.cpp new file mode 100644 index 000000000..f7209ea28 --- /dev/null +++ b/geo/count_points_in_triangle/sol/naive.cpp @@ -0,0 +1,67 @@ +/* + +O( N + M Q ) time solution + +can be accepted at N,M=500 and Q=10**6 + +*/ + +#include "fastio.hpp" +#include +#include +using i64 = long long; +#define rep(i,n) for(int i=0; i<(int)(n); i++) + +int main(){ + using namespace std; + using nachia::cin; + using nachia::cout; + int N; cin >> N; + vector Ax(N), Ay(N); + rep(i,N) cin >> Ax[i] >> Ay[i]; + int M; cin >> M; + vector Bx(M), By(M); + rep(i,M) cin >> Bx[i] >> By[i]; + + int Q; cin >> Q; + rep(qi, Q){ + int a,b,c; cin >> a >> b >> c; + i64 xab = Ax[b] - Ax[a]; + i64 yab = Ay[b] - Ay[a]; + i64 xac = Ax[c] - Ax[a]; + i64 yac = Ay[c] - Ay[a]; + if(xab * yac - yab * xac == 0){ + cout << "0\n"; + continue; + } + if(xab * yac - yab * xac < 0){ + swap(xab, xac); + swap(yab, yac); + swap(b, c); + } + // c + // + // a -----> b + int ans = 0; + rep(m,M){ + bool ok = true; + rep(t,3){ + i64 xV = Ax[b] - Ax[a]; + i64 yV = Ay[b] - Ay[a]; + i64 xW = Bx[m] - Ax[a]; + i64 yW = By[m] - Ay[a]; + if(xV * yW - yV * xW <= 0){ + // a ---V--> b + // -_ + // W-_ + // ->x (border ng) + ok = false; + } + swap(a,b); swap(b,c); + } + if(ok) ans++; + } + cout << ans << '\n'; + } + return 0; +} diff --git a/geo/count_points_in_triangle/task.md b/geo/count_points_in_triangle/task.md new file mode 100644 index 000000000..f0eb7f8c5 --- /dev/null +++ b/geo/count_points_in_triangle/task.md @@ -0,0 +1,55 @@ +## @{keyword.statement} + +@{lang.en} +Given 2D-points $A _ k=(x _ k, y _ k)$ $(k=0,1,\ldots ,N-1)$ and 2D-points $B _ k=(p _ k, q _ k)$ $(k=0,1,\ldots ,M-1)$ . Process the following $Q$ queries in order. + +* Given $a$ , $b$ , $c$ . Please output the number of points in $B _ 0,B _ 1,\ldots ,B _ {M-1}$ included in the convex hull of $3$ points $A _ a,A _ b,A _ c$ (**exclude border**) . + +@{lang.ja} +2D の点 $A _ k=(x _ k, y _ k)$ $(k=0,1,\ldots ,N-1)$ と 2D の点 $B _ k=(p _ k, q _ k)$ $(k=0,1,\ldots ,M-1)$ が与えられます。以下の $Q$ 個のクエリに順に答えてください。 + +* $a$ , $b$ , $c$ が与えられます。 $B _ 0,B _ 1,\ldots ,B _ {M-1}$ のうち、 $3$ 点 $A _ a,A _ b,A _ c$ の凸包の内部 (**境界を除く**) にあるものの個数を出力してください。 +@{lang.end} + +## @{keyword.constraints} + +@{lang.en} +- $1 \leq N \leq @{param.N_MAX}$ +- $1 \leq M \leq @{param.M_MAX}$ +- $|x _ i|, |y _ i| \leq @{param.X_AND_Y_ABS_MAX}$ +- $|p _ i|, |q _ i| \leq @{param.X_AND_Y_ABS_MAX}$ +- $1 \leq Q \leq @{param.Q_MAX}$ +- $0 \leq a,b,c \lt N$ +- They are all integers. +@{lang.ja} +- $1 \leq N \leq @{param.N_MAX}$ +- $1 \leq M \leq @{param.M_MAX}$ +- $|x _ i|, |y _ i| \leq @{param.X_AND_Y_ABS_MAX}$ +- $|p _ i|, |q _ i| \leq @{param.X_AND_Y_ABS_MAX}$ +- $1 \leq Q \leq @{param.Q_MAX}$ +- $0 \leq a,b,c \lt N$ +- これらはすべて整数 +@{lang.end} + +## @{keyword.input} + +``` +$N$ +$x _ 0$ $y _ 0$ +$x _ 1$ $y _ 1$ +$\ \vdots$ +$x _ {N-1}$ $y _ {N-1}$ +$M$ +$p _ 0$ $q _ 0$ +$p _ 1$ $q _ 1$ +$\ \vdots$ +$p _ {M-1}$ $q_{M-1}$ +$Q$ +$a$ $b$ $c$ +$\ \vdots$ +$a$ $b$ $c$ +``` + +## @{keyword.sample} + +@{example.example_00} diff --git a/geo/count_points_in_triangle/verifier.cpp b/geo/count_points_in_triangle/verifier.cpp new file mode 100644 index 000000000..e67a52c77 --- /dev/null +++ b/geo/count_points_in_triangle/verifier.cpp @@ -0,0 +1,35 @@ +#include "testlib.h" +#include "params.h" + +int main() { + registerValidation(); + + int n = inf.readInt(1, N_MAX); + inf.readChar('\n'); + for (int i = 0; i < n; i++) { + inf.readInt(-X_AND_Y_ABS_MAX, X_AND_Y_ABS_MAX); + inf.readChar(' '); + inf.readInt(-X_AND_Y_ABS_MAX, X_AND_Y_ABS_MAX); + inf.readChar('\n'); + } + int m = inf.readInt(1, M_MAX); + inf.readChar('\n'); + for (int i = 0; i < m; i++) { + inf.readInt(-X_AND_Y_ABS_MAX, X_AND_Y_ABS_MAX); + inf.readChar(' '); + inf.readInt(-X_AND_Y_ABS_MAX, X_AND_Y_ABS_MAX); + inf.readChar('\n'); + } + int q = inf.readInt(1, Q_MAX); + inf.readChar('\n'); + for (int i = 0; i < q; i++) { + inf.readInt(0, n-1); + inf.readChar(' '); + inf.readInt(0, n-1); + inf.readChar(' '); + inf.readInt(0, n-1); + inf.readChar('\n'); + } + inf.readEof(); + return 0; +}