結果
| 問題 |
No.2602 Real Collider
|
| コンテスト | |
| ユーザー |
沙耶花
|
| 提出日時 | 2024-01-12 22:37:45 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 8,468 bytes |
| コンパイル時間 | 4,450 ms |
| コンパイル使用メモリ | 261,700 KB |
| 最終ジャッジ日時 | 2025-02-18 18:43:28 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 WA * 1 |
| other | AC * 70 WA * 8 |
ソースコード
#include <stdio.h>
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace atcoder;
using mint = modint998244353;
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define Inf32 1000000001
#define Inf64 1000000000000000001
const long double eps = 1e-10;
template <typename T>
struct point{
T x,y,rad,dir;
point(T a=0.0,T b=0.0){
x = a;
y = b;
fix_rd();
}
void update_x(T a,T b){
x = a*x + b;
fix_rd();
}
void update_x(T a){
update_x(0.0,a);
}
void update_y(T a,T b){
y = a*y + b;
fix_rd();
}
void update_y(T a){
update_y(0.0,a);
}
void update_rad(T a,T b){
rad = a*rad + b;
fix_xy();
}
void update_rad(T a){
update_rad(0.0,a);
}
void update_dir(T a,T b){
dir = a*dir + b;
fix_xy();
}
void update_dir(T a){
update_dir(0.0,a);
}
void fix_xy(){
x = rad * cos(dir);
y = rad * sin(dir);
fix_rd();
}
void fix_rd(){
rad = hypot(x,y);
if(rad==0.0)dir=0.0;
else dir = atan2(y,x);
fix_zero();
}
void fix_zero(){
if(abs(x)<eps)x = 0.0;
if(abs(y)<eps)y = 0.0;
if(abs(rad)<eps)rad = 0.0;
if(abs(dir)<eps)dir = 0.0;
}
void normalize(){
T s = size();
update_x(1.0/s,0.0);
update_y(1.0/s,0.0);
}
T get_dis(point<T> V){
return hypot(x-V.x,y-V.y);
}
T size(){
return get_dis(point<T>());
}
T angle_difference(point<T> V){
long double ret = dir - V.dir;
if(ret<-acos(-1.0))ret = acos(-1.0)*2.0+ret;
if(ret>acos(-1.0))ret=-acos(-1.0)*2.0+ret;
return ret;
}
//中点
point get_midpoint(point<T> V){
V.update_x(0.5,x/2.0);
V.update_y(0.5,y/2.0);
return V;
}
T get_inner_product(point<T> V){
return x*V.x+y*V.y;
}
T get_cross_product(point<T> V){
return x*V.y-y*V.x;
}
point &operator+=(const point<T> &another){
update_x(1,another.x);
update_y(1,another.y);
return (*this);
}
point &operator-=(const point<T> &another){
update_x(1,-another.x);
update_y(1,-another.y);
return (*this);
}
point operator+(const point<T> &another)const{
return (point(*this)+=another);
}
point operator-(const point<T> &another)const{
return (point(*this)-=another);
}
void show(){
cout<<x<<','<<y<<endl;
}
};
//a+tx
template <typename T>
struct line{
point<T> a,t;
line(){
}
line(point<T> V1,point<T> V2){
a=V1;
t=V2-V1;
}
T get_signed_dis(point<T> V){
point<long double> PA = a-V;
return PA.get_cross_product(t)/t.size();
}
T get_dis(point<T> V){
return abs(get_signed_dis(V));
}
point<T> get_projection(point<T> P){
T r = t.get_inner_product(P-a)/t.size();
point<T> temp = t;
temp.update_rad(0.0,r);
return a+temp;
}
point<T> get_cross_point(line<T> L){
point<T> ret(1e20,1e20);
if(abs(t.get_cross_product(L.t))<eps)return ret;
T d0 = L.get_signed_dis(a);
T d1 = L.get_signed_dis(a+t);
point<T> temp = t;
temp.x *= d0/(d1-d0);
temp.y *= d0/(d1-d0);
ret = a - temp;
return ret;
}
};
template <typename T>
struct segment{
point<T> V1,V2;
segment(point<T> a=point<T>(),point<T> b=point<T>()){
V1=a;
V2=b;
}
T get_dis(point<T> P){
T ret = 1e20;
line<T> L(V1,V2);
point<T> Q = L.get_projection(P);
if(Q.x+eps>min(V1.x,V2.x)&&Q.y+eps>min(V1.y,V2.y)
&&Q.x<max(V1.x,V2.x)+eps&&Q.y<max(V1.y,V2.y)+eps)ret = min(ret,Q.get_dis(P));
else{
ret = min(ret,P.get_dis(V1));
ret = min(ret,P.get_dis(V2));
}
return ret;
}
T get_dis(segment<T> l){
if(get_cross_point(l).x<1e20)return 0.0;
return min({get_dis(l.V1),get_dis(l.V2),l.get_dis(V1),l.get_dis(V2)});
}
point<T> get_cross_point(segment<T> l){
line<T> L1(V1,V2),L2(l.V1,l.V2);
point<T> P = L1.get_cross_point(L2);
if(get_dis(P)<eps&&l.get_dis(P)<eps)return P;
return point<T> (1e20,1e20);
}
};
template <typename T>
struct triangle{
point<T> V[3];
triangle(point<T> V1,point<T> V2,point<T> V3){
V[0] = V1;
V[1] = V2;
V[2] = V3;
}
point<T> get_circumcenter(){
line<T> L1(V[0],V[1]);
point<T> M1 = V[0].get_midpoint(V[1]);
L1 = line<T>(M1,L1.b,L1.a);
line<T> L2(V[1],V[2]);
point<T> M2 = V[1].get_midpoint(V[2]);
L2 = line<T>(M2,L2.b,L2.a);
return L1.get_cross_point(L2);
}
T get_signed_area(){
return ((V[1].x-V[0].x)*(V[2].y-V[0].y) - (V[2].x-V[0].x)*(V[1].y-V[0].y))/2.0;
}
T get_area(){
return abs(get_signed_area());
}
bool is_inside(point<T> P){
T S = triangle<T>(V[0],V[1],P).get_area() + triangle<T>(V[1],V[2],P).get_area() + triangle<T>(V[2],V[0],P).get_area();
return abs(S - get_area())<eps;
}
bool is_clockwise(){
point<T> X = V[1]-V[0],Y = V[2]-V[1];
return X.x*Y.y-X.y*Y.x < 0.0;
}
};
template <typename T>
struct polygon{
vector<point<T>> V;
polygon(vector<point<T>> v){
V = v;
}
bool is_convex(){
bool f = false;
for(int i=0;i<V.size();i++){
triangle<T> tri(V[i],V[(i+1)%V.size()],V[(i+2)%V.size()]);
if(i==0)f = tri.is_clockwise();
else{
if(tri.is_clockwise()!=f)return false;
}
}
return true;
}
T get_signed_area(){
T ret = 0.0;
for(int i=1;i<V.size()-1;i++){
triangle<T> tri(V[0],V[i],V[i+1]);
ret += tri.get_signed_area();
}
return ret;
}
T get_area(){
return abs(get_signed_area());
}
T get_diameter(){
vector<T> dis(V.size());
int now = 0;
for(int i=0;i<V.size();i++){
while(true){
int next = (now+1)%V.size();
if(V[i].get_dis(V[now])<V[i].get_dis(V[next])+eps){
now = next;
continue;
}
else{
break;
}
}
dis[i] = V[i].get_dis(V[now]);
}
T ret = 0.0;
for(int i=0;i<V.size();i++)ret = max(ret,dis[i]);
return ret;
}
bool is_on_side(point<T> P){
for(int i=0;i<V.size();i++){
segment<T> l(V[i],V[(i+1)%V.size()]);
if(l.get_dis(P)<eps)return true;
}
return false;
}
bool is_inside(point<T> P){
if(is_on_side(P))return true;
long double R = 0.0;
for(int i=0;i<V.size();i++){
point<T> p1(V[i]-P),p2(V[(i+1)%V.size()]-P);
R += p1.angle_difference(p2);
}
return abs(R)>=eps;
}
};
template <typename T>
struct circle{
point<T> C;
T R;
circle(point<T> c=point<T>(),T r=0.0){
C = c;
R = r;
}
vector<point<T>> get_cross_point(circle<T> C2){
vector<point<T>> ret;
T d = C.get_dis(C2.C);
if(d>R+C2.R+eps)return ret;
if(d+eps<abs(R-C2.R))return ret;
T cosine = (pow(R,2.0)+pow(d,2.0)-pow(C2.R,2.0))/(2.0*R*d);
T Rc = R*cosine;
T Rs = sqrt(pow(R,2.0)-pow(Rc,2.0));
point<T> e1 = (C2.C-C);
e1.update_rad(1.0/d,0.0);
point<T> e2 = e1;
e2.update_dir(1.0,acos(-1.0)/2.0);
e1.update_rad(Rc,0.0);
e2.update_rad(Rs,0.0);
ret.push_back(C + e1+e2);
e2.update_dir(1.0,-acos(-1.0));
ret.push_back(C+e1+e2);
return ret;
}
vector<point<T>> get_cross_point(line<T> L){
vector<point<T>> ret;
auto p = L.get_projection(C);
if(p.get_dis(C)>R+eps)return ret;
long double tr = pow(R,2.0) - pow(p.get_dis(C),2.0);
tr = sqrt(tr);
{
auto pp = L.t;
pp.update_rad(0.0,tr);
ret.push_back(p + pp);
}
{
auto pp = L.t;
pp.update_rad(0.0,-tr);
ret.push_back(p + pp);
}
return ret;
}
};
int main(){
int q;
cin>>q;
circle<long double> C;
{
vector<point<long double>> t(3);
rep(i,3){
long double x,y;
cin>>x>>y;
t[i]= point<long double>(x,y);
}
long double ok = 2e4,ng = 0;
rep(_,100){
long double mid = (ok+ng)/2.0;
vector<circle<long double>> cs(3);
rep(i,3){
cs[i] = circle<long double>(t[i],mid);
}
bool f = true;
vector<point<long double>> ps;
rep(i,3){
for(int j=i+1;j<3;j++){
auto ret = cs[i].get_cross_point(cs[j]);
rep(k,ret.size()){
ps.push_back(ret[k]);
}
}
}
f = false;
rep(i,ps.size()){
rep(j,3){
if(ps[i].get_dis(t[j])<=mid + eps)continue;
goto L;
}
f = true;
break;
L:;
}
if(f)ok = mid;
else ng = mid;
}
long double mid = ok;
vector<circle<long double>> cs(3);
rep(i,3){
cs[i] = circle<long double>(t[i],mid);
}
bool f = true;
vector<point<long double>> ps;
rep(i,3){
for(int j=i+1;j<3;j++){
auto ret = cs[i].get_cross_point(cs[j]);
rep(k,ret.size()){
ps.push_back(ret[k]);
}
}
}
f = false;
rep(i,ps.size()){
rep(j,3){
if(ps[i].get_dis(t[j])<=mid + eps)continue;
goto LL;
}
C.C = ps[i];
C.R = mid;
break;
LL:;
}
}
rep(_,q){
point<long double> t;
long double x,y;
cin>>x>>y;
t = point<long double>(x,y);
if(t.get_dis(C.C)<=C.R+eps)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
沙耶花