首页 > 代码库 > csu1377Putter && HOJ12816
csu1377Putter && HOJ12816
链接:(csu)http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1377
(HOJ)http://49.123.82.55/online/?action=problem&type=list&courseid=0&querytext=&pageno=57
题意:
给定凸多边形的点(按顺时针),多边形内一点沿某个方向运动,碰到边进行镜面反射,问在一条边不碰超过两次的情况下,有多少种不同的碰撞方法。多边形最多8条边。
思路:
枚举每一种情况,合理就对结果+1,枚举用dfs轻松加愉快。本题关键在于求出镜像点,然后以镜像点出发,对边进行考察,若能直线到达,则该点能被反射到,否则不能。
Code:
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <algorithm> 6 #define op operator 7 #define cp const P& 8 #define cn const 9 #define db double10 #define rt return11 using namespace std;12 cn db eps = 1e-9;13 cn db pi = acos(-1.0);14 inline int sig(db x) {return (x>eps) - (x<-eps);}15 16 struct P{17 db x, y;18 P(db a = 0.0, db b = 0.0) : x(a), y(b) {}19 void in() { scanf("%lf %lf", &x, &y);}20 void out(){ printf("%lf %lf\n", x, y);}21 bool op<(cp a)cn {return sig(x-a.x) ? sig(x-a.x) : sig(y-a.y);}22 P op-(cp a)cn {return P(x-a.x, y-a.y);}23 P op+(cp a)cn {return P(x+a.x, y+a.y);}24 db op^(cp a)cn {return x*a.y - y*a.x;}25 db cross(P a, P b) {return (a-*this) ^ (b-*this);}26 db op*(cp a)cn {return x*a.x + y*a.y;} //点积27 db dot(P a, P b) {return (a-*this) * (b-*this);}28 P op*(cn db &a)cn {return P(a*x, a*y);}29 bool op/(cp a)cn {return sig(x*a.y - y*a.x) == 0;}30 db dis() {return sqrt(x*x + y*y);}31 db dis(P a) {return (a-*this).dis();}32 P T() {return P(-y, x);}33 P roate(db d) {34 return P(x*cos(d) - y*sin(d), y*cos(d) + x*sin(d));35 }36 bool on(P a, P b) {return !sig(cross(a, b)) && sig(dot(a, b)) <= 0;} //点在线段上37 P Mirror_P(P a, P b) {38 P v1 = *this - a, v2 = b - a;39 db w = acos(v1*v2 / v1.dis() / v2.dis());40 int f = sig(v1^v2);41 w = 2*w*f;42 rt a + v1.roate(w);43 }44 }p[10], q;45 inline P inset(P a1, P b1, P a2, P b2) {46 db u = (b1^a1), z = b2^a2, w = (b1-a1) ^ (b2-a2);47 P v;48 v.x = ((b2.x-a2.x)*u - (b1.x-a1.x)*z) / w;49 v.y = ((b2.y-a2.y)*u - (b1.y-a1.y)*z) / w;50 rt v;51 }52 bool vis[10];53 int ans, n;54 bool if_insight(P q, int i, P a, P b) {55 if(sig(q.cross(b, p[i])) <= 0 && sig(q.cross(b, p[i+1])) <= 0) rt false;56 if(sig(q.cross(a, p[i])) >= 0 && sig(q.cross(a, p[i+1])) >= 0) rt false;57 rt true;58 }59 void dfs(P q, int k, int m, P a, P b) {60 if(vis[k]) rt ;61 if(m == n) { ++ans; rt ; }62 vis[k] = 1;63 q = q.Mirror_P(p[k], p[k+1]);64 for(int i = 0; i < n; ++i) {65 if(i != k && if_insight(q, i, a, b)) {66 P c , d;67 if(sig(q.cross(b, p[i])) < 0) c = inset(b, q, p[i], p[i+1]);68 else c = p[i];69 if(sig(q.cross(a, p[i+1])) > 0) d = inset(a, q, p[i], p[i+1]);70 else d = p[i+1];71 72 dfs(q, i, m+1, c, d);73 }74 }75 vis[k] = 0;76 }77 void solve() {78 p[n] = p[0];79 ans = 0;80 for(int i = 0; i < n; ++i)81 dfs(q, i, 1, p[i], p[i+1]);82 printf("%d\n", ans);83 rt ;84 }85 int main()86 {87 while(scanf("%d", &n), n) {88 q.in();89 for(int i = 0; i < n; ++i) p[i].in();90 memset(vis, 0, sizeof vis);91 solve();92 }93 return 0;94 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。