From 53430d28d452fee8fb64d88ca378b9e0a2b62153 Mon Sep 17 00:00:00 2001 From: Bruno Freitas Tissei <bft15@inf.ufpr.br> Date: Wed, 11 Sep 2019 16:06:07 -0300 Subject: [PATCH] Organize geometry and add SBC15 Signed-off-by: Bruno Freitas Tissei <bft15@inf.ufpr.br> --- algorithms/geometry/circle.cpp | 53 ++++----- algorithms/geometry/convex_hull.cpp | 21 ++-- algorithms/geometry/geometry_primitives.cpp | 120 -------------------- algorithms/geometry/point.cpp | 50 ++++++++ algorithms/geometry/polygon.cpp | 65 +++++++++++ algorithms/geometry/primitives.cpp | 8 ++ algorithms/geometry/rotating_calipers.cpp | 41 ------- algorithms/geometry/segment.cpp | 48 ++++++++ contests/Cadernaveis/LA5138.cpp | 68 ++++++----- contests/SBC15/A.cpp | 65 +++++++++++ contests/SBC15/B.cpp | 40 +++++++ contests/SBC15/C.cpp | 30 +++++ contests/SBC15/D.cpp | 92 +++++++++++++++ contests/SBC15/E.cpp | 52 +++++++++ contests/SBC15/F.cpp | 41 +++++++ contests/SBC15/J.cpp | 40 +++++++ contests/SBC15/K.cpp | 67 +++++++++++ 17 files changed, 675 insertions(+), 226 deletions(-) delete mode 100644 algorithms/geometry/geometry_primitives.cpp create mode 100644 algorithms/geometry/point.cpp create mode 100644 algorithms/geometry/polygon.cpp create mode 100644 algorithms/geometry/primitives.cpp delete mode 100644 algorithms/geometry/rotating_calipers.cpp create mode 100644 algorithms/geometry/segment.cpp create mode 100644 contests/SBC15/A.cpp create mode 100644 contests/SBC15/B.cpp create mode 100644 contests/SBC15/C.cpp create mode 100644 contests/SBC15/D.cpp create mode 100644 contests/SBC15/E.cpp create mode 100644 contests/SBC15/F.cpp create mode 100644 contests/SBC15/J.cpp create mode 100644 contests/SBC15/K.cpp diff --git a/algorithms/geometry/circle.cpp b/algorithms/geometry/circle.cpp index 91f3555..179a8ba 100644 --- a/algorithms/geometry/circle.cpp +++ b/algorithms/geometry/circle.cpp @@ -1,16 +1,16 @@ /// Circle struct Circle { - Point<double> c; + Point<> c; double r; - Circle(Point<double> c, double r) : c(c), r(r) {} + Circle(Point<> c, double r) : c(c), r(r) {} // Circumcircle - Circle(Point<double> a, Point<double> b, Point<double> c) { - Point<double> u((b - a).y, -(b - a).x); - Point<double> v((c - a).y, -(c - a).x); - Point<double> n = (c - b)*0.5; + Circle(Point<> a, Point<> b, Point<> c) { + Point<> u((b - a).y, -(b - a).x); + Point<> v((c - a).y, -(c - a).x); + Point<> n = (c - b)*0.5; double t = u.cross(n) / v.cross(u); @@ -18,30 +18,31 @@ struct Circle { this->r = dist(this->c, a); } - bool contains(Point<double> p) { - return (dist(c, p) <= r + EPS); - } -}; - -// Minumum enclosing circle -Circle min_enclosing(vector<Point<double>> p) { - random_shuffle(all(p)); - Circle C(p[0], 0.0); + // Minimum enclosing circle: O(n) + Circle(vector<Point<>> p) { + random_shuffle(all(p)); + Circle C(p[0], 0.0); - for (int i = 0; i < p.size(); ++i) { - if (C.contains(p[i])) continue; - C = Circle(p[i], 0.0); + for (int i = 0; i < p.size(); ++i) { + if (C.contains(p[i])) continue; + C = Circle(p[i], 0.0); - for (int j = 0; j < i; ++j) { - if (C.contains(p[j])) continue; - C = Circle((p[j] + p[i])*0.5, 0.5*dist(p[j], p[i])); + for (int j = 0; j < i; ++j) { + if (C.contains(p[j])) continue; + C = Circle((p[j] + p[i])*0.5, 0.5*dist(p[j], p[i])); - for (int k = 0; k < j; ++k) { - if (C.contains(p[k])) continue; - C = Circle(p[j], p[i], p[k]); + for (int k = 0; k < j; ++k) { + if (C.contains(p[k])) continue; + C = Circle(p[j], p[i], p[k]); + } } } + + this->c = C.c; + this->r = C.r; } - return C; -} + bool contains(Point<double> p) { + return (dist(c, p) <= r + EPS); + } +}; diff --git a/algorithms/geometry/convex_hull.cpp b/algorithms/geometry/convex_hull.cpp index 1e29a4e..279e717 100644 --- a/algorithms/geometry/convex_hull.cpp +++ b/algorithms/geometry/convex_hull.cpp @@ -3,31 +3,28 @@ /// Time: O(n log n) /// Space: O(n) -using point = pair<double,double>; - -bool cw(point a, point b, point c) { - return (b.fi - a.fi) * (c.se - a.se) - \ - (b.se - a.se) * (c.fi - a.fi) < 0; +bool cw(Point<> a, Point<> b, Point<> c) { + return (b - a).cross(c - a) <= 0; } -vector<point> convex_hull(vector<point> &v) { +vector<Point<>> convex_hull(vector<Point<>> &v) { int k = 0; - vector<point> ans(v.size() * 2); + vector<Point<>> ans(v.size() * 2); - sort(all(v), [](const point &a, const point &b) { - return (a.fi == b.fi) ? (a.se < b.se) : (a.fi < b.fi); + sort(all(v), [](const Point<> &a, const Point<> &b) { + return (a.x == b.x) ? (a.y < b.y) : (a.x < b.x); }); for (int i = 0; i < v.size(); ++i) { - for (; k >= 2 && !cw(ans[k-2], ans[k-1], v[i]); --k); + for (; k >= 2 && cw(ans[k-2], ans[k-1], v[i]); --k); ans[k++] = v[i]; } for (int i = v.size() - 2, t = k + 1; i >= 0; --i) { - for (; k >= t && !cw(ans[k-2], ans[k-1], v[i]); --k); + for (; k >= t && cw(ans[k-2], ans[k-1], v[i]); --k); ans[k++] = v[i]; } - ans.resize(k - 1); + ans.resize(k); return ans; } diff --git a/algorithms/geometry/geometry_primitives.cpp b/algorithms/geometry/geometry_primitives.cpp deleted file mode 100644 index 041afc2..0000000 --- a/algorithms/geometry/geometry_primitives.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/// Geometry Primitives - -#define to_deg(x) ((x * 180.0) / M_PI) -#define to_rad(x) ((x * M_PI) / 180.0) - -template <typename T> -struct Point { - T x, y; - - Point() {} - Point(T x, T y) : x(x), y(y) {} - - Point operator+(Point p) { return Point(x+p.x, y+p.y); } - Point operator-(Point p) { return Point(x-p.x, y-p.y); } - Point operator*(T s) { return Point(x*s, y*s); } - - T dot(Point p) { return (x*p.x) + (y*p.y); } - T cross(Point p) { return (x*p.y) - (y*p.x); } - - // Returns angle between this and p: - // atan2(y, x) is in the range [-180,180]. To - // get [0, 360], atan2(-y, -x) + 180 is used - T angle(Point p) { - return to_deg(atan2(-cross(p), -dot(p))) + 180.0; - } - - // Returns cosine value between this and p. - T cosine(Point p) { - return (dot(p) / (sqrt(dot(*this))*sqrt(p.dot(p)))); - } - - // Returns sine value between this and p. - T sine(Point p) { - return (cross(p) / (sqrt(dot(*this))*sqrt(p.dot(p)))); - } - - // Returns whether point is inside the triable - // abc or not. - bool inside_triagle(Point a, Point b, Point c) { - bool c1 = (*this - b).cross(a - b) < 0; - bool c2 = (*this - c).cross(b - c) < 0; - bool c3 = (*this - a).cross(c - a) < 0; - return c1 == c2 && c1 == c3; - } - - // Finds orientation of ordered triplet (a,b,c). - // Colinear (0), Clockwise (1), Counterclockwise (2) - static int orientation(Point a, Point b, Point c) { - T val = (b - a).cross(c - b); - if (val == 0) return 0; - return (val > 0) ? 1 : 2; - } -}; - -double dist(Point<double> a, Point<double> b) { - return hypot(a.x - b.x, a.y - b.y); -} - -template <typename T> -struct Segment { - Point<T> a, b; - - Segment(Point a, Point b) : a(a), b(b) {} - - // Checks if points p and q are on the same side - // of the segment. - bool same_side(Point p, Point q) { - T cpp = (p - a).cross(b - a); - T cpq = (q - a).cross(b - a); - return ((cpp > 0 && cpq > 0) || - (cpp < 0 && cpq < 0)); - } - - // Checks if point p is on the segment. - bool on_segment(Point p) { - return (p.x <= max(a.x, b.x) && - p.x >= min(a.x, b.x) && - p.y <= max(a.y, b.y) && - p.y >= min(a.y, b.y)); - } - - // Checks if segment intersects with s. - bool intersect(Segment s) { - int o1 = Point::orientation( a, b, s.a); - int o2 = Point::orientation( a, b, s.b); - int o3 = Point::orientation(s.a, s.b, a); - int o4 = Point::orientation(s.a, s.b, b); - - if (o1 != o2 && o3 != o4) - return true; - - if (o1 == 0 && on_segment(s.a)) return true; - if (o2 == 0 && on_segment(s.b)) return true; - if (o3 == 0 && s.on_segment(a)) return true; - if (o4 == 0 && s.on_segment(b)) return true; - - return false; - } -}; - -template <typename T> -struct Polygon { - vector<Point<T>> v; - - Polygon() {} - Polygon(vector<Point> v) : v(v) {} - - // Adds a vertex to the polygon. - void add_point(Point p) { v.pb(p); } - - // Returns area of polygon (only works when vertices - // are sorted in clockwise or counterclockwise order). - double area() { - double ans = 0; - for (int i = 0; i < v.size(); ++i) - ans += v[i].cross(v[(i + 1) % v.size()]); - - return fabs(ans) / 2.0; - } -}; diff --git a/algorithms/geometry/point.cpp b/algorithms/geometry/point.cpp new file mode 100644 index 0000000..a3f66ab --- /dev/null +++ b/algorithms/geometry/point.cpp @@ -0,0 +1,50 @@ +/// Point + +template <typename T = double> +struct Point { + T x, y; + + Point() {} + Point(T x, T y) : x(x), y(y) {} + + Point operator+(Point p) { return Point(x+p.x, y+p.y); } + Point operator-(Point p) { return Point(x-p.x, y-p.y); } + Point operator*(T s) { return Point(x*s, y*s); } + + T dot(Point p) { return (x*p.x) + (y*p.y); } + T cross(Point p) { return (x*p.y) - (y*p.x); } + + // Returns angle between this and p: + // atan2(y, x) is in the range [-180,180]. To + // get [0, 360], atan2(-y, -x) + 180 is used + T angle(Point p) { + return to_deg(atan2(-cross(p), -dot(p))) + 180.0; + } + + // Returns cosine value between this and p. + T cosine(Point p) { + return (dot(p) / (sqrt(dot(*this))*sqrt(p.dot(p)))); + } + + // Returns sine value between this and p. + T sine(Point p) { + return (cross(p) / (sqrt(dot(*this))*sqrt(p.dot(p)))); + } + + // Returns whether point is inside the triable + // abc or not. + bool inside_triagle(Point a, Point b, Point c) { + bool c1 = (*this - b).cross(a - b) < 0; + bool c2 = (*this - c).cross(b - c) < 0; + bool c3 = (*this - a).cross(c - a) < 0; + return c1 == c2 && c1 == c3; + } + + // Finds orientation of ordered triplet (a,b,c). + // Colinear (0), Clockwise (1), Counterclockwise (2) + static int orientation(Point<> a, Point<> b, Point<> c) { + T val = (b - a).cross(c - b); + if (val == 0) return 0; + return (val > 0) ? 1 : 2; + } +}; diff --git a/algorithms/geometry/polygon.cpp b/algorithms/geometry/polygon.cpp new file mode 100644 index 0000000..97db8be --- /dev/null +++ b/algorithms/geometry/polygon.cpp @@ -0,0 +1,65 @@ +/// Polygon + +template <typename T = double> +struct Polygon { + vector<Point<T>> v; + + Polygon() {} + Polygon(vector<Point<T>> v) : v(v) {} + + // Adds a vertex to the polygon. + void add_point(Point<T> p) { v.pb(p); } + + // Returns area of polygon (only works when vertices + // are sorted in clockwise or counterclockwise order). + double area() { + double ans = 0; + for (int i = 0; i < v.size(); ++i) + ans += v[i].cross(v[(i + 1) % v.size()]); + + return fabs(ans) / 2.0; + } + + // Rotating Calipers + double width() { + vector<Point<>> h = convex_hull(v); + + int n = h.size() - 1; + double ans = 1e14; + + h[0] = h[n]; + for (int i = 1, j = 1; i <= n; ++i) { + while ((h[i] - h[i-1]).cross(h[j%n+1] - h[i-1]) > + (h[i] - h[i-1]).cross(h[j] - h[i-1])) + j = j % n + 1; + + Segment<> seg(h[i], h[i-1]); + ans = min(ans, seg.dist(h[j])); + } + + return ans; + } + + // Rotating Calipers + double diameter() { + vector<Point<>> h = convex_hull(v); + + if (h.size() == 1) return 0; + if (h.size() == 2) return dist(h[0], h[1]); + + int n = h.size() - 1; + double ans = -1e14; + + h[0] = h[n]; + for (int i = 1, j = 1; i <= n; ++i) { + while ((h[i] - h[i-1]).cross(h[j%n+1] - h[i-1]) > + (h[i] - h[i-1]).cross(h[j] - h[i-1])) + j = j % n + 1; + + ans = max(ans, dist(h[j], h[i])); + ans = max(ans, dist(h[j], h[i-1])); + } + + return ans; + } +}; diff --git a/algorithms/geometry/primitives.cpp b/algorithms/geometry/primitives.cpp new file mode 100644 index 0000000..51cee51 --- /dev/null +++ b/algorithms/geometry/primitives.cpp @@ -0,0 +1,8 @@ +/// Geometry Primitives + +#define to_deg(x) ((x * 180.0) / M_PI) +#define to_rad(x) ((x * M_PI) / 180.0) + +double dist(Point<> a, Point<> b) { + return hypot(a.x - b.x, a.y - b.y); +} diff --git a/algorithms/geometry/rotating_calipers.cpp b/algorithms/geometry/rotating_calipers.cpp deleted file mode 100644 index 65fd15e..0000000 --- a/algorithms/geometry/rotating_calipers.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/// Rotating Calipers -/// -/// Time: O(n log n) -/// Space: O(n) - -double dist(point a, point b) { - return hypot(a.fi - b.fi, a.se - b.se); -} - -double area(point a, point b, point c) { - return abs((b.fi - a.fi) * (c.se - a.se) - \ - (b.se - a.se) * (c.fi - a.fi)); -} - -double diameter(vector<point> &v) { - vector<point> h = convex_hull(v); - - int m = h.size(); - if (m == 1) return 0; - if (m == 2) return dist(h[0], h[1]); - - int k = 1; - while (area(h[m-1], h[0], h[(k+1)%m]) > - area(h[m-1], h[0], h[k])) - k++; - - double ans = 0; - for (int i = 0, j = k; i <= k && j < m; ++i) { - ans = max(ans, dist(h[i], h[j])); - - while (i < m && - area(h[i], h[(i+1)%m], h[(j+1)%m]) > - area(h[i], h[(i+1)%m], h[j])) - { - ans = max(ans, dist(h[i], h[(j+1)%m])); - j++; - } - } - - return ans; -} diff --git a/algorithms/geometry/segment.cpp b/algorithms/geometry/segment.cpp new file mode 100644 index 0000000..aaf4d97 --- /dev/null +++ b/algorithms/geometry/segment.cpp @@ -0,0 +1,48 @@ +/// Segment + +template <typename T = double> +struct Segment { + Point<T> a, b; + + Segment(Point<T> a, Point<T> b) : a(a), b(b) {} + + // Checks if points p and q are on the same side + // of the segment. + bool same_side(Point<T> p, Point<T> q) { + T cpp = (p - a).cross(b - a); + T cpq = (q - a).cross(b - a); + return ((cpp > 0 && cpq > 0) || + (cpp < 0 && cpq < 0)); + } + + // Checks if point p is on the segment. + bool on_segment(Point<T> p) { + return (p.x <= max(a.x, b.x) && + p.x >= min(a.x, b.x) && + p.y <= max(a.y, b.y) && + p.y >= min(a.y, b.y)); + } + + // Distance between segment and point + double dist(Point<T> p) { + return (a - b).cross(p - b)/sqrt((b - a).dot(b - a)); + } + + // Checks if segment intersects with s. + bool intersect(Segment<T> s) { + int o1 = Point<>::orientation( a, b, s.a); + int o2 = Point<>::orientation( a, b, s.b); + int o3 = Point<>::orientation(s.a, s.b, a); + int o4 = Point<>::orientation(s.a, s.b, b); + + if (o1 != o2 && o3 != o4) + return true; + + if (o1 == 0 && on_segment(s.a)) return true; + if (o2 == 0 && on_segment(s.b)) return true; + if (o3 == 0 && s.on_segment(a)) return true; + if (o4 == 0 && s.on_segment(b)) return true; + + return false; + } +}; diff --git a/contests/Cadernaveis/LA5138.cpp b/contests/Cadernaveis/LA5138.cpp index 732fc82..fb0707b 100644 --- a/contests/Cadernaveis/LA5138.cpp +++ b/contests/Cadernaveis/LA5138.cpp @@ -19,27 +19,42 @@ using namespace std; using ll = long long; using ii = pair<int,int>; -using point = pair<double,double>; +template <typename T = double> +struct Point { + T x, y; -bool cw(point a, point b, point c) { - return (b.fi - a.fi) * (c.se - a.se) - \ - (b.se - a.se) * (c.fi - a.fi) <= 0; -} + Point() {} + Point(T x, T y) : x(x), y(y) {} + + Point operator+(Point p) { return Point(x+p.x, y+p.y); } + Point operator-(Point p) { return Point(x-p.x, y-p.y); } + Point operator*(T s) { return Point(x*s, y*s); } + + T dot(Point p) { return (x*p.x) + (y*p.y); } + T cross(Point p) { return (x*p.y) - (y*p.x); } +}; -//double cross(point a, point b, point c) { -// return (b.fi - a.fi) * (c.se - a.se) - \ -// (b.se - a.se) * (c.fi - a.fi); -//} -double cross(const point &o, const point &a, const point &b) { - return (a.fi - o.fi) * (b.se - o.se) - (a.se - o.se) * (b.fi - o.fi); +bool cw(Point<> a, Point<> b, Point<> c) { + return (b - a).cross(c - a) <= 0; } -vector<point> convex_hull(vector<point> &v) { +template <typename T = double> +struct Segment { + Point<T> a, b; + + Segment(Point<T> a, Point<T> b) : a(a), b(b) {} + + double dist(Point<T> p) { + return (a - b).cross(p - b)/sqrt((b - a).dot(b - a)); + } +}; + +vector<Point<>> convex_hull(vector<Point<>> &v) { int k = 0; - vector<point> ans(v.size() * 2); + vector<Point<>> ans(v.size() * 2); - sort(all(v), [](const point &a, const point &b) { - return (a.fi == b.fi) ? (a.se < b.se) : (a.fi < b.fi); + sort(all(v), [](const Point<> &a, const Point<> &b) { + return (a.x == b.x) ? (a.y < b.y) : (a.x < b.x); }); for (int i = 0; i < v.size(); ++i) { @@ -56,21 +71,20 @@ vector<point> convex_hull(vector<point> &v) { return ans; } -double dist_line(point p, point a, point b) { - return cross(b, a, p) / sqrt((b.se-a.se) * (b.se-a.se) + (b.fi-a.fi)*(b.fi-a.fi)); -} +double width(vector<Point<>> &v) { + vector<Point<>> h = convex_hull(v); -double width(vector<point> &v) { - vector<point> h = convex_hull(v); int n = h.size() - 1; - int j = 1; - double ans = 1e14; + h[0] = h[n]; - for (int i = 1; i <= n; ++i) { - while (cross(h[i-1], h[i], h[j%n+1]) > cross(h[i-1], h[i], h[j])) + for (int i = 1, j = 1; i <= n; ++i) { + while ((h[i] - h[i-1]).cross(h[j%n+1] - h[i-1]) > + (h[i] - h[i-1]).cross(h[j] - h[i-1])) j = j % n + 1; - ans = min(ans, dist_line(h[j], h[i], h[i-1])); + + Segment<> seg(h[i], h[i-1]); + ans = min(ans, seg.dist(h[j])); } return ceil(ans*100)/100; @@ -83,9 +97,9 @@ int main() { int n, cas = 1; while (cin >> n && n) { - vector<point> v(n); + vector<Point<>> v(n); for (int i = 0; i < n; ++i) - cin >> v[i].fi >> v[i].se; + cin >> v[i].x >> v[i].y; cout << "Case " << cas << ": " << width(v) << ende; cas++; diff --git a/contests/SBC15/A.cpp b/contests/SBC15/A.cpp new file mode 100644 index 0000000..e2a4903 --- /dev/null +++ b/contests/SBC15/A.cpp @@ -0,0 +1,65 @@ +#include <bits/stdc++.h> + +#define MAX 10101 +#define EPS 1e-6 +#define MOD 1000000007 +#define inf 0x3f3f3f3f +#define llinf 0x3f3f3f3f3f3f3f3f + +#define fi first +#define se second +#define pb push_back +#define ende '\n' + +#define all(x) (x).begin(), (x).end() +#define rall(x) (x).rbegin(), (x).rend() +#define mset(x, y) memset(&x, (y), sizeof(x)) + +using namespace std; + +using ll = long long; +using ii = pair<int,int>; + +vector<ii> graph[MAX]; +vector<ii> gg[MAX]; + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + int c, v; cin >> c >> v; + for (int i = 0; i < v; ++i) { + int a, b, w; cin >> a >> b >> w; + graph[a].pb({b, w}); + graph[b].pb({a, w}); + } + + for (int i = 1; i <= c; ++i) + for (auto j : graph[i]) + for (auto k : graph[j.fi]) + gg[i].pb({k.fi, j.se + k.se}); + + vector<int> vis(c + 1, 0); + vector<int> dist(c + 1, inf); + + set<ii> pq; + pq.insert({0, 1}); + dist[1] = 0; + while (!pq.empty()) { + int u = pq.begin()->se; + pq.erase(pq.begin()); + + if (vis[u]) continue; + vis[u] = 1; + + for (auto i : gg[u]) + if (!vis[i.fi] && dist[i.fi] > dist[u] + i.se) { + dist[i.fi] = dist[u] + i.se; + pq.insert({dist[i.fi], i.fi}); + } + } + + if (dist[c] == inf) dist[c] = -1; + cout << dist[c] << ende; + return 0; +} diff --git a/contests/SBC15/B.cpp b/contests/SBC15/B.cpp new file mode 100644 index 0000000..b0f5abd --- /dev/null +++ b/contests/SBC15/B.cpp @@ -0,0 +1,40 @@ +#include <bits/stdc++.h> + +#define EPS 1e-6 +#define MOD 1000000007 +#define inf 0x3f3f3f3f +#define llinf 0x3f3f3f3f3f3f3f3f + +#define fi first +#define se second +#define pb push_back +#define ende '\n' + +#define all(x) (x).begin(), (x).end() +#define rall(x) (x).rbegin(), (x).rend() +#define mset(x, y) memset(&x, (y), sizeof(x)) + +using namespace std; + +using ll = long long; +using ii = pair<int,int>; + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + int n, c; cin >> n >> c; + vector<int> v(n); + vector<vector<int>> dp(n, vector<int>(2)); + + for (auto &i : v) cin >> i; + + dp[n-1] = {0, v[n-1]}; + for (int i = n - 2; i >= 0; --i) { + dp[i][1] = max(dp[i + 1][0] + v[i], dp[i + 1][1]); + dp[i][0] = max(dp[i + 1][0], dp[i + 1][1] - (v[i] + c)); + } + + cout << max(0, dp[0][0]) << ende; + return 0; +} diff --git a/contests/SBC15/C.cpp b/contests/SBC15/C.cpp new file mode 100644 index 0000000..ee90cb2 --- /dev/null +++ b/contests/SBC15/C.cpp @@ -0,0 +1,30 @@ +#include <bits/stdc++.h> + +#define EPS 1e-6 +#define MOD 1000000007 +#define inf 0x3f3f3f3f +#define llinf 0x3f3f3f3f3f3f3f3f + +#define fi first +#define se second +#define pb push_back +#define ende '\n' + +#define all(x) (x).begin(), (x).end() +#define rall(x) (x).rbegin(), (x).rend() +#define mset(x, y) memset(&x, (y), sizeof(x)) + +using namespace std; + +using ll = long long; +using ii = pair<int,int>; + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + int a, b; cin >> a >> b; + cout << max(a, b) << ende; + + return 0; +} diff --git a/contests/SBC15/D.cpp b/contests/SBC15/D.cpp new file mode 100644 index 0000000..13a3552 --- /dev/null +++ b/contests/SBC15/D.cpp @@ -0,0 +1,92 @@ +#include <bits/stdc++.h> + +#define EPS 1e-6 +#define MOD 1000000007 +#define inf 0x3f3f3f3f +#define llinf 0x3f3f3f3f3f3f3f3f + +#define fi first +#define se second +#define pb push_back +#define ende '\n' + +#define all(x) (x).begin(), (x).end() +#define rall(x) (x).rbegin(), (x).rend() +#define mset(x, y) memset(&x, (y), sizeof(x)) + +using namespace std; + +using ll = long long; +using ii = pair<int,int>; + +int c[101], r[101]; +string mat[101][101]; + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + int n, m; cin >> n >> m; + + int k = 0; + map<string,int> M; + for (int i = 0; i < n; ++i) { + for (int j = 0; j < m; ++j) { + cin >> mat[i][j]; + M[mat[i][j]] = k++; + } + cin >> c[i]; + } + + for (int j = 0; j < m; ++j) + cin >> r[j]; + + map<string,int> ans; + for (int i = 0; i < M.size(); ++i) { + string found = "nono"; + + for (int j = 0; j < n; ++j) { + map<string,int> S; + for (int k = 0; k < m; ++k) + S[mat[j][k]]++; + + if (S.find("aaa") != S.end()) + S.erase("aaa"); + + if (S.size() == 1) { + found = S.begin()->fi; + ans[S.begin()->fi] = c[j] / S.begin()->se; + break; + } + } + + if (found == "nono") { + for (int j = 0; j < m; ++j) { + map<string,int> S; + for (int k = 0; k < n; ++k) + S[mat[k][j]]++; + + if (S.find("aaa") != S.end()) + S.erase("aaa"); + + if (S.size() == 1) { + found = S.begin()->fi; + ans[S.begin()->fi] = r[j] / S.begin()->se; + break; + } + } + } + + for (int j = 0; j < n; ++j) + for (int k = 0; k < m; ++k) + if (mat[j][k] == found) { + r[k] -= ans[found]; + c[j] -= ans[found]; + mat[j][k] = "aaa"; + } + } + + for (auto i : ans) + cout << i.fi << " " << i.se << ende; + return 0; +} diff --git a/contests/SBC15/E.cpp b/contests/SBC15/E.cpp new file mode 100644 index 0000000..ffb2680 --- /dev/null +++ b/contests/SBC15/E.cpp @@ -0,0 +1,52 @@ +#include <bits/stdc++.h> + +#define EPS 1e-6 +#define MOD 1000000007 +#define inf 0x3f3f3f3f +#define llinf 0x3f3f3f3f3f3f3f3f + +#define fi first +#define se second +#define pb push_back +#define ende '\n' + +#define all(x) (x).begin(), (x).end() +#define rall(x) (x).rbegin(), (x).rend() +#define mset(x, y) memset(&x, (y), sizeof(x)) + +using namespace std; + +using ll = long long; +using ii = pair<int,int>; + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + ll n, b; cin >> n >> b; + if (b <= n) + return cout << 1 << " " << b, 0; + + auto f = [&](ll x) { + ll sum = ((n - 1LL) * n); + return sum - (x * (x+1LL)); + }; + + ll k = n - 1; + for (ll bb = n / 2; bb >= 1; bb /= 2) + while (k - bb >= 0 && n + f(k - bb) <= b) + k -= bb; + + ll base = n + f(k); + if (base + k <= b) + base += k; + + ll kk = 0; + for (ll bb = n / 2; bb >= 1; bb /= 2) + while (base + kk + bb < ) + + cout << f(6) << ende; + cout << k << ende; + cout << base << ende; + return 0; +} diff --git a/contests/SBC15/F.cpp b/contests/SBC15/F.cpp new file mode 100644 index 0000000..3f7986e --- /dev/null +++ b/contests/SBC15/F.cpp @@ -0,0 +1,41 @@ +#include <bits/stdc++.h> + +#define EPS 1e-6 +#define MOD 1000000007 +#define inf 0x3f3f3f3f +#define llinf 0x3f3f3f3f3f3f3f3f + +#define fi first +#define se second +#define pb push_back +#define ende '\n' + +#define all(x) (x).begin(), (x).end() +#define rall(x) (x).rbegin(), (x).rend() +#define mset(x, y) memset(&x, (y), sizeof(x)) + +using namespace std; + +using ll = long long; +using ii = pair<int,int>; + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + int n; cin >> n; + vector<int> fat(10); + fat[0] = 1; + for (int i = 1; i < 10; ++i) + fat[i] = fat[i-1] * i; + + int ans = 0; + for (int i = 9; i >= 1; --i) + while (n - fat[i] >= 0) { + n -= fat[i]; + ans++; + } + + cout << ans << ende; + return 0; +} diff --git a/contests/SBC15/J.cpp b/contests/SBC15/J.cpp new file mode 100644 index 0000000..f463b2f --- /dev/null +++ b/contests/SBC15/J.cpp @@ -0,0 +1,40 @@ +#include <bits/stdc++.h> + +#define EPS 1e-6 +#define MOD 1000000007 +#define inf 0x3f3f3f3f +#define llinf 0x3f3f3f3f3f3f3f3f + +#define fi first +#define se second +#define pb push_back +#define ende '\n' + +#define all(x) (x).begin(), (x).end() +#define rall(x) (x).rbegin(), (x).rend() +#define mset(x, y) memset(&x, (y), sizeof(x)) + +using namespace std; + +using ll = long long; +using ii = pair<int,int>; + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + int j, r; cin >> j >> r; + vector<int> p(j, 0); + for (int i = 0; i < j*r; ++i) { + int x; cin >> x; + p[i%j] += x; + } + + int ans = 0; + for (int i = 0; i < j; ++i) + if (p[ans] <= p[i]) + ans = i; + + cout << ans + 1 << ende; + return 0; +} diff --git a/contests/SBC15/K.cpp b/contests/SBC15/K.cpp new file mode 100644 index 0000000..0735dbf --- /dev/null +++ b/contests/SBC15/K.cpp @@ -0,0 +1,67 @@ +#include <bits/stdc++.h> + +#define MAX 2010 +#define EPS 1e-6 +#define MOD 1000000007 +#define inf 0x3f3f3f3f +#define llinf 0x3f3f3f3f3f3f3f3f + +#define fi first +#define se second +#define pb push_back +#define ende '\n' + +#define all(x) (x).begin(), (x).end() +#define rall(x) (x).rbegin(), (x).rend() +#define mset(x, y) memset(&x, (y), sizeof(x)) + +using namespace std; + +using ll = long long; +using ii = pair<int,int>; + +int n; +string s; +int v[MAX]; +ii dp[MAX][MAX]; + +ii operator+(const ii &a, const ii &b) { + return {a.fi + b.fi, a.se + b.se}; +} + +ii solve(int l, int r) { + if (l > r) return ii(0, 0); + if (l == r) return ii(v[l], 1); + + if (dp[l][r].fi != -1) + return dp[l][r]; + + ii op = {-inf, -inf}; + if (s[l] == s[r]) + op = solve(l + 1, r - 1) + ii(v[l] + v[r], 2); + + return dp[l][r] = max({ + op, + solve(l + 1, r - 1), + solve(l + 1, r), + solve(l, r - 1) + }); +} + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + cin >> s >> n; + for (int i = 0; i < n; ++i) { + int x; cin >> x; + v[x - 1] = 1; + } + + for (int i = 0; i < MAX; ++i) + for (int j = 0; j < MAX; ++j) + dp[i][j] = {-1, -1}; + + cout << solve(0, s.size() - 1).se << ende; + return 0; +} -- GitLab