HDU_4978_A simple probability problem.(推导or精度枚举)
来源:互联网 发布:淘宝店铺怎么搜索不到 编辑:程序博客网 时间:2024/05/22 06:14
题型:计算几何
题意:
一个平面上有无数个相距为D的平行直线,一个直径为D的均匀圆盘上有N个点组成的多边形,随机将圆盘扔在平面上,求平面上的某直线穿过多边形的概率。
分析:
首先分析圆盘上只有一条线段的情况,设线段长为l。若线段与平面上直线垂直,则线段与直线相交的概率如图1
如果旋转一下角度,概率就变为如图2所示
那么随机扔线段与直线相交的概率为
对于n个点,先求一个凸包。
凸包的每一条边与直线相交的概率都是
那么总概率就是概率之和,但是考虑到凸包的一个性质,即:任意一条直线穿过凸包,都会与两条边长相交,所以总概率是
所以求一个凸包周长即可。
但是在比赛过程中,对于我等脑残弱智党来说,推出上述公式简直难,俺们会的就是暴力了。。。
于是想到枚举精度,将180度切成若干分,每次度数加一点算出一个l,随后算一个平均值就是概率。
然后,我就开始暴力提交了,我将180度切成3000分卡过。
公式正解代码:
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<queue>#define LL long long#define mt(a,b) memset(a,b,sizeof(a))using namespace std;const double eps = 1e-10;const double PI = acos(-1.0);struct point { double x,y;} p[123],res[123];int n,d;bool operator < (const point &l, const point &r) { return l.y < r.y || (fabs(l.y- r.y)<eps && l.x < r.x);}class ConvexHull { //凸包 bool mult(point sp, point ep, point op) { return (sp.x - op.x) * (ep.y - op.y)>= (ep.x - op.x) * (sp.y - op.y); }public: int graham(int n,point p[],point res[]) {//多边形点个数和点数组,凸包存res sort(p, p + n); if (n == 0) return 0; res[0] = p[0]; if (n == 1) return 1; res[1] = p[1]; if (n == 2) return 2; res[2] = p[2]; int top=1; for (int i = 2; i < n; i++) { while (top && mult(p[i], res[top], res[top-1])) top--; res[++top] = p[i]; } int len = top; res[++top] = p[n - 2]; for (int i = n - 3; i >= 0; i--) { while (top!=len && mult(p[i], res[top],res[top-1])) top--; res[++top] = p[i]; } return top; // 返回凸包中点的个数 }} tu;double caldis(point A,point B) { return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));}double Perimeter() { double ans = caldis(res[n-1],res[0]); for(int i=0; i<n-1; i++) { ans += caldis(res[i],res[i+1]); } return ans;}int main() {// freopen("in.txt","r",stdin);// freopen("out.txt","w",stdout); int cas = 0,_; scanf("%d",&_); while(_--) { scanf("%d%d",&n,&d); for(int i=0; i<n; i++) { scanf("%lf%lf",&p[i].x,&p[i].y); } n = tu.graham(n,p,res); double c = Perimeter();// printf("C = %.4f\n",c); printf("Case #%d: %.4f\n",++cas,c/(PI*d)); } return 0;}
枚举精度代码:
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<queue>#define LL long long#define mt(a,b) memset(a,b,sizeof(a))using namespace std;const double eps = 1e-10;const double PI = acos(-1.0);const double inf = 1e8;struct point { double x,y;} p[123],res[123];int n,d;bool operator < (const point &l, const point &r) { return l.y < r.y || (fabs(l.y- r.y)<eps && l.x < r.x);}class ConvexHull { //凸包 bool mult(point sp, point ep, point op) { return (sp.x - op.x) * (ep.y - op.y)>= (ep.x - op.x) * (sp.y - op.y); }public: int graham(int n,point p[],point res[]) {//多边形点个数和点数组,凸包存res sort(p, p + n); if (n == 0) return 0; res[0] = p[0]; if (n == 1) return 1; res[1] = p[1]; if (n == 2) return 2; res[2] = p[2]; int top=1; for (int i = 2; i < n; i++) { while (top && mult(p[i], res[top], res[top-1])) top--; res[++top] = p[i]; } int len = top; res[++top] = p[n - 2]; for (int i = n - 3; i >= 0; i--) { while (top!=len && mult(p[i], res[top],res[top-1])) top--; res[++top] = p[i]; } return top; // 返回凸包中点的个数 }} tu;double caldis(point A,point B) { return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));}double Perimeter() { double ans = caldis(res[n-1],res[0]); for(int i=0; i<n-1; i++) { ans += caldis(res[i],res[i+1]); } return ans;}struct line { point a,b;};point intersection(point u1,point u2,point v1,point v2) { point ret=u1; double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x)) /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x)); ret.x+=(u2.x-u1.x)*t; ret.y+=(u2.y-u1.y)*t; return ret;}point ptoline(point p,line l) {///点到直线上的最近点 point t=p; t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x; return intersection(p,t,l.a,l.b);}int main() {// freopen("in.txt","r",stdin);// freopen("out.txt","w",stdout); int cas = 0,_; scanf("%d",&_); while(_--) { scanf("%d%d",&n,&d); for(int i=0; i<n; i++) { scanf("%lf%lf",&p[i].x,&p[i].y); } n = tu.graham(n,p,res); ///90度枚举3000次 double zl = 180.0 / 3000; double l; double sum = 0.00; for(double i=0; i<180; i+=zl) { point S,T;///S为左下点,T为右上点 double cita = i * PI / 180.0; for(int j=0; j<n; j++) { point tmp; double k = tan(cita); line ll; ll.a.x = 0.0; ll.a.y = 0.0; ll.b.x = 1.0; ll.b.y = k; tmp = ptoline(res[j],ll); if(j==0) { S.x = tmp.x; S.y = tmp.y; T.x = tmp.x; T.y = tmp.y; } S = min(S,tmp); T = max(T,tmp); } l = caldis(S,T); sum+=l; }// printf("sum = %.4f\n",sum); printf("Case #%d: %.4f\n",++cas,sum/3000/d); } return 0;}
0 0
- HDU_4978_A simple probability problem.(推导or精度枚举)
- HDU 4978 A simple probability problem
- HDU 4978 A simple probability problem
- 【凸包】 HDOJ 4978 A simple probability problem.
- 【HDU】4978 A simple probability problem. 凸包
- HDU 4978 A simple probability problem 【凸包】【几何】
- HDU 4978 A simple probability problem.(思维+凸包)
- 【HDU】4978 A simple probability problem. 凸包
- HDU 4143 A Simple Problem (枚举暴力)
- HDU 4978 A simple probability problem. 蒲丰投针问题 + 二维凸包
- Game with probability Problem
- hdu5974——A Simple Math Problem(gcd推导+数学+解方程组)
- simple problem
- poj 3468 A Simple Problem with Integers(线段树区间更新 or 树状数组区间更新)
- poj3468 A Simple Problem with Integers 基础线段树or树状数组
- bzoj2318 Spoj4060 game with probability Problem
- Problem 100 Arranged probability (丢番图方程)
- 【bzoj2318】 Spoj4060 game with probability Problem
- tween动画重新触发
- asp.net中TreeView异步延迟加载
- startActivityForResult() 中requestCode 和 resultCode 的作用
- XP下IOS开发环境搭建
- Python Twisted框架中socket通讯
- HDU_4978_A simple probability problem.(推导or精度枚举)
- Eclipse的Tomcat插件安装
- HDU 2225 Asteroids!(三维BFS)
- Linux LVM硬盘管理及LVM扩容
- OpenCV基础
- 8.27 super hero
- 智能人员定位实训平台(CY-RYDW-100)
- IE6中margin-bottom为负值时失效
- STRUTS基本工作流程