Sherlock and Geometry

  • + 0 comments

    OwO

    //distance from p1 to p2 to the power of 2
    inline long distance_p2(long p1x, long p1y, long p2x, long p2y) {
    	return std::abs((p1x - p2x) * (p1x - p2x) + (p1y - p2y) * (p1y - p2y));
    }
    
    //distance from s to the nearest point on p1 - p2 to the power of 2
    float distance_to_line_p2(long sx, long sy, long p1x, long p1y, long p2x, long p2y) {
    	long
    		e1 = distance_p2(sx, sy, p1x, p1y),//s - p1
    		e2 = distance_p2(sx, sy, p2x, p2y),//s - p2
    		e3 = distance_p2(p1x, p1y, p2x, p2y);//p1 - p2
    
    	if (e3 + e1 <= e2 || e3 + e2 <= e1) {
    		//if s-p1-p2 or 2-p2-p1 is an obtuse (or right) angle, the nearest point is one of the two vertices
    		return std::min(e1, e2);
    	}
    
    	//else return the length of altitude (from s) to the power of two
    
    	long long num = (long long)e1 * e3 * 4 - ((long long)e1 + e3 - e2) * ((long long)e1 + e3 - e2);
    
    	return num / (4.0 * e3);
    }
    
    std::string solve(int x, int y, int r, const std::vector<int>& t1, const std::vector<int>& t2, const std::vector<int>& t3) {
    	long r2 = r * r;
    	long
    		d1 = distance_p2(x, y, t1[0], t1[1]),
    		d2 = distance_p2(x, y, t2[0], t2[1]),
    		d3 = distance_p2(x, y, t3[0], t3[1]);
    
    	//if one of the vertices is on the circle
    	if (d1 == r2 || d2 == r2 || d3 == r2)return "YES";
    
    	//if all vertices is inside the circle
    	if (d1 < r2 && d2 < r2 && d3 < r2)return "NO";
    
    	//if there exist at least two vertices, one inside the circle and the other on the outside of the circle
    	if ((d1 < r2 || d2 < r2 || d3 < r2) && (d1 > r2 || d2 > r2 || d3 > r2)) return "YES";
    
    	//all vertices should be outside of the circle now
    
    	//if the nearest point of t1-t2 (from (x,y)) is inside (or on) the circle
    	if (distance_to_line_p2(x, y, t1[0], t1[1], t2[0], t2[1]) <= r2)return "YES";
    	//else all points of t1-t2 is outside the circle
    
    	if (distance_to_line_p2(x, y, t1[0], t1[1], t3[0], t3[1]) <= r2)return "YES";
    
    	if (distance_to_line_p2(x, y, t2[0], t2[1], t3[0], t3[1]) <= r2)return "YES";
    
    	return "NO";
    }