很裸的一道计算几何对吧
每一个询问我们就只需要易操作将他展开就好了。。
很显然爆搜中可以删几个不可能的中途状态点
时间上界是
2n∗m
的
然后我是在linux打的。。。调戏了很久毛了搬到Windows上才发现是一个double打成了int。。。。。各种不爽
#include<cstdio>
#include<iostream>
#include<cstdio>
#include<set>
using namespace std;
inline double abs(double a){return a<0?-a:a;}
const
double eps=0.000001;
struct Point
{
double x,y;
inline friend bool operator ==(Point a,Point b) {
return abs(a.x-b.x)<eps&&abs(a.y-b.y)<eps;
}
};
const
int INF=1<<29;
const Point Wa=(Point){-INF,-INF};
const Point Single=(Point){INF,INF};
struct Line
{
Point start,end;
};
inline double Cross(Point a,Point b)
{return a.x*b.y-a.y*b.x;}
inline Point Rotato(Point a,Line b)
{
Point tpa,tpb;
tpa.x=a.x-b.start.x;
tpa.y=a.y-b.start.y;
tpb.x=b.end.x-b.start.x;
tpb.y=b.end.y-b.start.y;
Point res;
if(Cross(tpb,tpa)>eps)
{
if(abs(b.start.x-b.end.x)<eps)
res.x=2*b.start.x-a.x,res.y=a.y;
else if(abs(b.start.y-b.end.y)<eps)
res.x=a.x,res.y=2*b.start.y-a.y;
else
{
double k=b.end.y-b.start.y,k1;
k/=b.end.x-b.start.x;
k1=-1/k;double b1=b.end.x*b.start.y-b.end.y*b.start.x,b2;
b1/=b.end.x-b.start.x;
if(abs(a.x)<eps)b2=a.y;
else b2=a.y-k1*a.x;
res.x=(b2-b1)/(k-k1);res.y=k*res.x+b1;
res.x*=2,res.y*=2,res.x-=a.x,res.y-=a.y;
}
return res;
}
if(Cross(tpb,tpa)<-eps)
return Wa;
return Wa;
}
Line Oper[10001];
int ans;
int n;
inline bool Can(Point a)
{return a.x>eps&&a.x<100-eps&&a.y>eps&&a.y<100-eps;}
void DFS(Point a,int t)
{
Point fl;
if(t==0)
{if(Can(a))ans++;return ;}
fl=Rotato(a,Oper[t]) ;
if(fl==Wa)return;
else if(fl==Single)DFS(a,t-1);
else DFS(fl,t-1),DFS(a,t-1);
}
int main()
{
int n,m;scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf",&Oper[i].start.x),
scanf("%lf",&Oper[i].start.y),
scanf("%lf",&Oper[i].end.x),
scanf("%lf",&Oper[i].end.y);
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
Point re;ans=0;
scanf("%lf%lf",&re.x,&re.y);
DFS(re,n);
printf("%d\n",ans);
}
return 0;
}