uvalive 7331 Hovering Hornet 半平面交+概率期望
题意:一个骰子在一个人正方形内,蜜蜂在任意一个位置可以出现,问看到点数的期望。
思路:半平面交+概率期望
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<cstdlib> 6 #include<string> 7 #include<cmath> 8 #include<vector> 9 using namespace std; 10 const int maxn=1e5+7; 11 const double eps=1e-8; 12 const double pi=acos(-1); 13 14 double dcmp(double x) 15 { 16 if(fabs(x) < eps) return 0; 17 else return x < 0 ? -1 : 1; 18 } 19 20 struct Point 21 { 22 double x, y; 23 Point(double x=0, double y=0):x(x),y(y) { } 24 }; 25 26 typedef Point Vector; 27 28 Vector operator + (const Point& A, const Point& B) 29 { 30 return Vector(A.x+B.x, A.y+B.y); 31 } 32 33 Vector operator - (const Point& A, const Point& B) 34 { 35 return Vector(A.x-B.x, A.y-B.y); 36 } 37 38 Vector operator * (const Point& A, double v) 39 { 40 return Vector(A.x*v, A.y*v); 41 } 42 43 Vector operator / (const Point& A, double v) 44 { 45 return Vector(A.x/v, A.y/v); 46 } 47 48 double Cross(const Vector& A, const Vector& B) 49 { 50 return A.x*B.y - A.y*B.x; 51 } 52 53 double Dot(const Vector& A, const Vector& B) 54 { 55 return A.x*B.x + A.y*B.y; 56 } 57 58 double Length(const Vector& A) 59 { 60 return sqrt(Dot(A,A)); 61 } 62 63 Vector Rotate(Vector A,double rad) 64 { 65 return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad)); 66 } 67 68 bool operator < (const Point& p1, const Point& p2) 69 { 70 return p1.x < p2.x || (p1.x == p2.x && p1.y < p2.y); 71 } 72 73 bool operator == (const Point& p1, const Point& p2) 74 { 75 return p1.x == p2.x && p1.y == p2.y; 76 } 77 78 Vector Normal(Vector A) 79 { 80 double L=Length(A); 81 return Vector(-A.y/L,A.x/L); 82 } 83 struct Line 84 { 85 Point P; 86 Vector v; 87 double ang; 88 Line() {} 89 Line(Point P, Vector v):P(P),v(v) 90 { 91 ang = atan2(v.y, v.x); 92 } 93 bool operator < (const Line& L) const 94 { 95 return ang < L.ang; 96 } 97 }; 98 99 bool OnLeft(const Line& L, const Point& p) 100 { 101 return Cross(L.v, p-L.P) > 0; 102 } 103 104 105 Point GetLineIntersection(const Line& a, const Line& b) 106 { 107 Vector u = a.P-b.P; 108 double t = Cross(b.v, u) / Cross(a.v, b.v); 109 return a.P+a.v*t; 110 } 111 112 const double INF = 1e8; 113 114 Point ansPoly[maxn]; 115 int HalfplaneIntersection(vector<Line> L) //L为切割平面的直线集合,求半平面交,返回点的个数,点存在anspoly数组中 116 { 117 int n = L.size(); 118 sort(L.begin(), L.end()); // 按极角排序 119 int first, last; // 双端队列的第一个元素和最后一个元素的下标 120 vector<Point> p(n); // p[i]为q[i]和q[i+1]的交点 121 vector<Line> q(n); // 122 q[first=last=0] = L[0]; // 123 for(int i = 1; i < n; i++) 124 { 125 while(first < last && !OnLeft(L[i], p[last-1])) last--; 126 while(first < last && !OnLeft(L[i], p[first])) first++; 127 q[++last] = L[i]; 128 if(fabs(Cross(q[last].v, q[last-1].v)) < eps) // 129 { 130 last--; 131 if(OnLeft(q[last], L[i].P)) q[last] = L[i]; 132 } 133 if(first < last) p[last-1] = GetLineIntersection(q[last-1], q[last]); 134 } 135 while(first < last && !OnLeft(q[first], p[last-1])) last--; // 136 if(last - first <= 1) return 0; // 137 p[last] = GetLineIntersection(q[last], q[first]); // 138 // 从deque复制到输出中 139 int index=0; 140 for(int i = first; i <= last; i++) ansPoly[index++]=p[i]; 141 return index; 142 } 143 144 double PolygonArea(int n,Point *p) 145 { 146 double area=0; 147 for(int i=1; i<n-1; i++) 148 area+=Cross(p[i]-p[0],p[i+1]-p[0]); 149 return area/2; 150 } 151 // vector<Line> vec; 152 // vec.push_back(Line(Point(0,0),Point(1,0))); 153 // vec.push_back(Line(Point(10000,0),Point(0,1))); 154 // vec.push_back(Line(Point(10000,10000),Point(-1,0))); 155 // vec.push_back(Line(Point(0,10000),Point(0,-1))); 156 // Vector v=(p[1]-p[0]); 157 // vec.push_back(Line((p[1]+p[0])*0.5,Normal(v))); 158 // v=(p[2]-p[0]); 159 // vec.push_back(Line((p[2]+p[0])*0.5,Normal(v))); 160 // int m=HalfplaneIntersection(vec); 161 // double ans=PolygonArea(m,ansPoly); 162 // printf("%.3f\n",ans/(1.0*10000*10000)); 163 Point p[5]; 164 void CC(Point *p) 165 { 166 for(int i=0; i<maxn; i++) 167 { 168 p[i].x=0; 169 p[i].y=0; 170 } 171 } 172 int main() 173 { 174 // freopen("in.txt","r",stdin); 175 double a1,a2,a3,a4,a5,a6; 176 a5=(5.0*5*4)/(5*5*5-1); 177 a2=0; 178 while(cin>>p[0].x>>p[0].y>>p[1].x>>p[1].y>>p[2].x>>p[2].y>>p[3].x>>p[3].y) 179 { 180 CC(ansPoly); 181 vector<Line>vec; 182 vec.push_back(Line(Point(p[0].x,p[0].y),Point(p[1].x-p[0].x,p[1].y-p[0].y))); 183 vec.push_back(Line(Point(p[1].x,p[1].y),Point(p[2].x-p[1].x,p[2].y-p[1].y))); 184 vec.push_back(Line(Point(p[2].x,p[2].y),Point(p[3].x-p[2].x,p[3].y-p[2].y))); 185 vec.push_back(Line(Point(p[3].x,p[3].y),Point(p[0].x-p[3].x,p[0].y-p[3].y))); 186 vec.push_back(Line(Point(-0.5,-0.5),Point(-1,0))); 187 int sou_num=HalfplaneIntersection(vec); 188 a1=PolygonArea(sou_num,ansPoly); 189 // cout<<"a1:"<<a1<<endl; 190 // cout<<"sou_num:"<<sou_num<<endl; 191 // CC(ansPoly); 192 vec.clear(); 193 vec.push_back(Line(Point(p[0].x,p[0].y),Point(p[1].x-p[0].x,p[1].y-p[0].y))); 194 vec.push_back(Line(Point(p[1].x,p[1].y),Point(p[2].x-p[1].x,p[2].y-p[1].y))); 195 vec.push_back(Line(Point(p[2].x,p[2].y),Point(p[3].x-p[2].x,p[3].y-p[2].y))); 196 vec.push_back(Line(Point(p[3].x,p[3].y),Point(p[0].x-p[3].x,p[0].y-p[3].y))); 197 vec.push_back(Line(Point(-0.5,-0.5),Point(0,1))); 198 int west_num=HalfplaneIntersection(vec); 199 // cout<<ansPoly[3].y<<endl; 200 a4=PolygonArea(west_num,ansPoly); 201 // cout<<"a4:"<<a4<<endl; 202 // cout<<"west_num:"<<west_num<<endl; 203 CC(ansPoly); 204 vec.clear(); 205 vec.push_back(Line(Point(p[0].x,p[0].y),Point(p[1].x-p[0].x,p[1].y-p[0].y))); 206 vec.push_back(Line(Point(p[1].x,p[1].y),Point(p[2].x-p[1].x,p[2].y-p[1].y))); 207 vec.push_back(Line(Point(p[2].x,p[2].y),Point(p[3].x-p[2].x,p[3].y-p[2].y))); 208 vec.push_back(Line(Point(p[3].x,p[3].y),Point(p[0].x-p[3].x,p[0].y-p[3].y))); 209 vec.push_back(Line(Point(-0.5,0.5),Point(1,0))); 210 int nor_num=HalfplaneIntersection(vec); 211 a6=PolygonArea(nor_num,ansPoly); 212 // cout<<"a6:"<<a6<<endl; 213 // cout<<"nor_num:"<<nor_num<<endl; 214 CC(ansPoly); 215 vec.clear(); 216 vec.push_back(Line(Point(p[0].x,p[0].y),Point(p[1].x-p[0].x,p[1].y-p[0].y))); 217 vec.push_back(Line(Point(p[1].x,p[1].y),Point(p[2].x-p[1].x,p[2].y-p[1].y))); 218 vec.push_back(Line(Point(p[2].x,p[2].y),Point(p[3].x-p[2].x,p[3].y-p[2].y))); 219 vec.push_back(Line(Point(p[3].x,p[3].y),Point(p[0].x-p[3].x,p[0].y-p[3].y))); 220 vec.push_back(Line(Point(0.5,0.5),Point(0,-1))); 221 int east_num=HalfplaneIntersection(vec); 222 a3=PolygonArea(east_num,ansPoly); 223 // cout<<"a3:"<<a3<<endl; 224 // cout<<"east_num:"<<east_num<<endl; 225 long double ans1,ans2,ans3,ans4,ans5,ans6; 226 double ans; 227 // anss=(5.0*a1)/(5*5*5-1)+2*(5.0*a2)/(5*5*5-1)+3*(5.0*a3)/(5*5*5-1)+4*(5.0*a4)/(5*5*5-1)+a5*5.0+6*(5.0*a6)/(5*5*5-1); 228 ans1=(5.0*a1)/(5*5*5-1); 229 // cout<<"ans1:"<<ans1<<endl; 230 ans2=(5.0*a2)/(5*5*5-1); 231 // cout<<"ans2:"<<ans2<<endl; 232 ans3=3*(5.0*a3)/(5*5*5-1); 233 // cout<<"ans3:"<<ans3<<endl; 234 ans4=4*(5.0*a4)/(5*5*5-1); 235 // cout<<"ans4:"<<ans4<<endl; 236 ans5=5*a5; 237 // cout<<"ans5:"<<ans5<<endl; 238 ans6=6*(5.0*a6)/(5*5*5-1); 239 // cout<<"ans6:"<<ans6<<endl; 240 ans=ans1+ans2+ans3+ans4+ans5+ans6; 241 printf("%.10lf\n",ans); 242 } 243 return 0; 244 }