# BZOJ1074: [SCOI2007]折纸origami

14 篇文章 0 订阅

#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;
}
• 0
点赞
• 0
收藏
觉得还不错? 一键收藏
• 0
评论
01-08 99
10-31 183
02-17 110
07-15
12-01 514
09-29 120
03-13 450

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。