bzoj1074: [SCOI2007]折纸origami

从后往前逆推

const int N = 10;
struct Point {
	DB Ox, Oy;
	Point(){}
	Point(DB _Ox, DB _Oy) : Ox(_Ox), Oy(_Oy) {}
	friend Point operator -(Point a, Point b) { return Point(a.Ox-b.Ox, a.Oy-b.Oy); }
	friend Point operator + (Point a, Point b){ return Point(a.Ox + b.Ox, a.Oy + b.Oy); }
	DB Len() { return sqrt(Ox * Ox + Oy * Oy); }
	friend Point operator /(Point a, DB c) { return Point(a.Ox/c, a.Oy/c); }
	friend Point operator  * (Point a, DB c) { return Point(a.Ox * c, a.Oy * c); }
} P[1 << N];
struct Line {
	Point P1, P2;
} Dat[N];
bool Hash[1 << N];
int n, m;

inline void Solve();
inline void Input() {
	scanf("%d", &n);
	For(i, 1, n) scanf("%lf%lf%lf%lf", &Dat[i].P1.Ox, &Dat[i].P1.Oy, &Dat[i].P2.Ox, &Dat[i].P2.Oy);
	scanf("%d", &m);
}

inline DB Cross(Point a, Point b, Point c) {
	return(b.Ox - a.Ox) * (c.Oy - a.Oy) - (b.Oy - a.Oy) * (c.Ox - a.Ox);
}

inline DB Dist(Point P1, Point P2) {
	DB Ox = P1.Ox - P2.Ox, Oy = P1.Oy - P2.Oy;
	return sqrt(Ox * Ox + Oy * Oy);
}

inline DB Dist(Point P, Line Dat) { return fabs(Cross(P, Dat.P1, Dat.P2)) / Dist(Dat.P1, Dat.P2); }

inline Point Get(Point P, Line Dat) {
	Point A = Dat.P2 - Dat.P1;
	Point B(A.Oy, -A.Ox);
	DB h = Dist(P, Dat);
	B = B / B.Len() * h;
	return P + B * 2;
}

inline bool In(Point P) {
	return P.Ox > 0 && P.Ox < 100 && P.Oy > 0 && P.Oy < 100;
}

inline void Solve() {
	while(m--) {
		int Cnt = 1;
		clr(Hash, 0);
		scanf("%lf%lf", &P[1].Ox, &P[1].Oy);
		Ford(i, n, 1) {
			int t = Cnt;
			For(j, 1, t)
				if(!Hash[j]) {
					if(Cross(Dat[i].P1, Dat[i].P2, P[j]) > 0) P[++Cnt] = Get(P[j], Dat[i]);
					else Hash[j] = 1;
				}
		}
		int Ans = 0;
		For(i, 1, Cnt) Ans += (!Hash[i] && In(P[i]));
		printf("%d\n", Ans);
	}
}

int main(){
	#ifndef ONLINE_JUDGE
	SETIO("1074");
	#endif
	Input();
	Solve();
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值