# 【BZOJ】1074: [SCOI2007]折纸origami

http://www.lydsy.com/JudgeOnline/problem.php?id=1074

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <sstream>
using namespace std;
typedef long long ll;
#define pb push_back
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define error(x) (!(x)?puts("error"):0)
#define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next)
inline int getint() { static int r, k; r=0,k=1; static char c; c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }

const double eps=1e-6, PI2=acos(-1)*2;
int dcmp(double x) { return abs(x)<eps?0:(x<0?-1:1); }
struct iP { double x, y; iP(double _x=0, double _y=0):x(_x),y(_y){} void rd() { scanf("%lf%lf", &x, &y); } void D() { printf("x=%.2f, y=%.2f\n", x, y); }};
typedef iP iV;
iV operator-(iP a, iP b) { return iV(a.x-b.x, a.y-b.y); }
iV operator*(iV a, double b) { return iV(a.x*b, a.y*b); }
iV operator+(iP a, iV b) { return iP(a.x+b.x, a.y+b.y); }
bool operator==(iP a, iP b) { return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0; }
bool operator<(const iP &a, const iP &b) { return a.x==b.x?a.y<b.y:a.x<b.x; }
double cross(iV a, iV b) { return a.x*b.y-a.y*b.x; }
double dot(iV a, iV b) { return a.x*b.x+a.y*b.y; }
double Length(iV a) { return sqrt(dot(a, a)); }
double angle(iV a, iV b) { return acos(dot(a, b)/Length(a)/Length(b)); }
iV rot(iV v, double ang) { double cs=cos(ang), sn=sin(ang); return iV(v.x*cs-v.y*sn, v.y*cs+v.x*sn); }
struct iL { iP p; iV v; iL(){} iL(iP _p, iV _v):p(_p),v(_v) {} };

bool onL(iP a, iL l) { return dcmp(cross(a-l.p, l.v))<0; }
bool onR(iP a, iL l) { return dcmp(cross(a-l.p, l.v))>0; }
iP rev(iP a, iL l, int flag=1) { return l.p+rot(a-l.p, angle(a-l.p, l.v)*2*flag); }

const int Mx=1<<10;
iP h[Mx];
iL line[10];
int n, m, cnt;

void dfs(int dep, iP p) {
//if(dcmp(p.x)<=0 || dcmp(p.x-100)>=0 || dcmp(p.y)<=0 || dcmp(p.y-100)>=0) return;
h[cnt++]=p;
if(dep==0) return;
dfs(dep-1, p);
if(onL(p, line[dep])) dfs(dep-1, rev(p, line[dep], -1));
}
iP find(iP p) {
for1(i, 1, n) if(onR(p, line[i])) p=rev(p, line[i]); else if(!onL(p, line[i])) return iP(-1, -1);
return p;
}
bool check(iP &p) { if(dcmp(p.x)<=0 || dcmp(p.x-100)>=0 || dcmp(p.y)<=0 || dcmp(p.y-100)>=0) return false; return true; }
void work(iP &p) {
//if(dcmp(p.x)<=0 || dcmp(p.x-100)>=0 || dcmp(p.y)<=0 || dcmp(p.y-100)>=0) { puts("0"); return; }
int ans=0;
cnt=0;
dfs(n, p);
sort(h, h+cnt);
cnt=unique(h, h+cnt)-h;
rep(i, cnt) if(check(h[i]) && find(h[i])==p) ++ans;
printf("%d\n", ans);
}

int main() {
for1(i, 1, n) {
iP p1, p2;
p1.rd(); p2.rd();
line[i]=iL(p1, p2-p1);
}
for1(i, 1, m) {
iP p; p.rd();
work(p);
}
return 0;
}


posted @ 2015-01-08 22:05  iwtwiioi  阅读(340)  评论(0编辑  收藏  举报