RedSnowstorm's blog

By RedSnowstorm, history, 3 years ago, In English

I have written this convex hull code which uses the atan() function from cmatch in order to calculate the polar angle of a point(angle of it's vector with Ox), then sort the points by this value. My solution is currently getting TLE and I would like to know if this is due to the atan function being slow. I have searched and have not been able to find any information on its performance. If atan is the cause I would appreciate suggestions on easy ways to circumvent this problem. I know there are ways to do convex hull without atan, it's just that calculating this is a pretty intuitive and easy way for me and I'm curious if there's any way to do it efficiently. Here is the code:

#include <bits/stdc++.h>
#define double long double
using namespace std;

ifstream in("infasuratoare.in");
ofstream out("infasuratoare.out");


struct Point {
    double x,y;

    bool operator < (const Point other) const {
        if (y != other.y) {
            return y < other.y;
        }
        return x < other.x;
    }

    Point operator - (const Point other) const {
        return Point{x - other.x , y - other.y};
    }
};

double angle(Point p) { /// returns in radians the angle of the Point
    if (p.x == 0) {
        if (p.y == 0) return 0;
        if (p.y > 0) return M_PI/2;
        if (p.y < 0) return M_PI + M_PI / 2;
    }
    if (p.x > 0 && p.y > 0) {
        return atan(p.y / p.x);
    } else if ( p.x > 0 && p.y < 0) {
        return atan(p.y / p.x) + 2 * M_PI; 
    } else {
        return atan(p.y / p.x) + M_PI;
    }
}

bool rightTurn(Point a, Point b, Point c) {
    return angle(b - a) > angle(c - b);
}
vector<Point> pt;
int n;

vector<Point> convexHull() {
    vector<Point> res;

    Point lowLeft = pt[1];
    for (int i = 2; i <= n; i++) {
        if (pt[i] < lowLeft) {
            lowLeft = pt[i];
        }
    }
    sort(pt.begin() + 1, pt.end() , [&](Point a, Point b) {
        ///we move everyone down by this low left point, then sort this increasing by it's angle.
        return angle(a - lowLeft) < angle(b - lowLeft);
    });

    for (int i = 1; i <= n; i++) {
        while(res.size() >= 2 && rightTurn(res[(int)res.size() - 2] , res[(int)res.size() - 1] , pt[i])) {
            res.pop_back();
        }
        res.push_back(pt[i]);
    }
    return res;
}
int main() {

    in >> n;
    pt.resize(n + 1);
    for (int i = 1; i <= n; i++) {
        double x,y;
        in >> x >> y;
        pt[i] = {x,y};
    }


    auto hull = convexHull();

    out << fixed << setprecision(12);
    out << hull.size() << "\n";
    for (auto k : hull) {
        out << k.x << " " << k.y << "\n";
    }
    out << "\n";
}


Full text and comments »

  • Vote: I like it
  • -9
  • Vote: I do not like it

By RedSnowstorm, history, 6 years ago, In English

So sorry if I'm not using this feature properly, I was struggling with a problem and thought this would be a good place to ask for help. So here's the problem:

There are N light bulbs. Initially, all of them are turned off. You are given M switches with which you can switch the light bulbs on and off. The i-th switch will switch all the light bulbs in the subsequence starting at A[i] and ending at B[i] (All the turned off light bulbs are switched on and all the switched on ones are turned off).

You are also given a number X. Your job is to end with the light bulbs from 1 to X on, and all the ones from X+1 to N off, using the minimum number of switches possible.

Output the minimum number of switches to achieve the goal. If it is not possible to achieve the goal, output -1.

The input file are the numbers N M X followed by M (the number of switches) lines in which the i th line is A[i] and B[i] (the parameters for the switches)

N<=100 000 M<=200 000 example: IN OUT 5 3 4 3 1 3 3 4 3 3

Full text and comments »

  • Vote: I like it
  • +5
  • Vote: I do not like it