与六题擦边,最终五题,还有待提高。。。。
就讲讲我最后悔的那题吧(其他还不会- -!)
hdu 4316,方法的话题解已经说了
然后我犯了一个无比愚蠢的错误,把天花板的高度写成了200!!坑爹有木有啊
就这样与六题擦肩而过
#include <cmath>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const double INF = 1000000000.0;
const int maxn = 1010;
const double eps = 1e-8;
inline int sgn(double x) {return fabs(x)<eps?0:(x>0?1:-1);}
struct Point{
double x,y;
Point(double tx=0,double ty=0){x=tx;y=ty;}
bool operator == (const Point& t) const {
return sgn(x-t.x)==0 && sgn(y-t.y)==0;
}
}p[maxn],st[maxn],pp[maxn],points[maxn];
struct Seg{Point s,e;};
double Cross(Point a,Point b,Point c){
return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
/***** 凸包 ****************************************************************************/
bool cmpyx(Point a, Point b) {
if ( fabs(a.y - b.y)>eps )
return a.y +eps< b.y;
return a.x +eps < b.x;
}
void Grahamxy(Point *p, int &n) { // 水平序(住:两倍空间)
if ( n < 3 )
return;
int i, m=0, top=1;
sort(p, p+n, cmpyx);
for (i=n; i < 2*n-1; i++)
p[i] = p[2*n-2-i];
for (i=2; i < 2*n-1; i++) {
while ( top > m && Cross(p[top], p[i], p[top-1]) < eps )
top--;
p[++top] = p[i];
if ( i == n-1 ) m = top;
}
n = top;
}
//半平面交
bool outside(Seg seg,Point p){return Cross(seg.s,seg.e,p)>eps;}//strictly outside the ploygon
bool inside(Seg seg,Point p){return Cross(seg.s,seg.e,p)<-eps;}//strictly inside the ploygon
Point Intersect(Point p1, Point p2, Point p3, Point p4) {
double a1, b1, c1, a2, b2, c2, d;Point p;
a1 = p1.y - p2.y; b1 = p2.x - p1.x; c1 = p1.x*p2.y - p2.x*p1.y;
a2 = p3.y - p4.y; b2 = p4.x - p3.x; c2 = p3.x*p4.y - p4.x*p3.y;
d = a1*b2 - a2*b1;
if ( fabs(d) < eps ) return false;
p.x = (-c1*b2 + c2*b1) / d;
p.y = (-a1*c2 + a2*c1) / d;
return p;
}
int n,ban_tot;
void CUT(Seg seg){//points must be clockwise
int i,tot=0;
for(i=1;i<=ban_tot;i++){
if(!outside(seg,p[i])) pp[++tot]=p[i];//p[i] :inside or on the boundary
else {//p[i]: must be outside
if(inside(seg,p[i-1])) pp[++tot]=Intersect(seg.s,seg.e,p[i],p[i-1]);//p[i-1] must be inside
if(inside(seg,p[i+1])) pp[++tot]=Intersect(seg.s,seg.e,p[i],p[i+1]);//p[i+1] must be inside
}
}ban_tot=tot;
pp[tot+1]=pp[1];pp[0]=pp[tot];
memcpy(p,pp,sizeof(pp));
}
double getarea(Point *p,int n){
int i;
double area=0;
for(i=0;i<n;i++) area+=p[(i+1)%n].y*(p[i].x-p[(i+2)%n].x);
return fabs(area/2);
}
struct MACHINE{
double x,y,z;
}mac[maxn],cam[5];
Seg ts[20000];
Point tp[maxn];
int main(){
int n;
while(scanf("%d",&n)!=EOF){
for(int i=1;i<=n;i++) scanf("%lf%lf%lf",&mac[i].x,&mac[i].y,&mac[i].z);
for(int i=1;i<=3;i++){
scanf("%lf%lf",&cam[i].x,&cam[i].y);
cam[i].z=100;
}
int cnt=0;
int num=0;
p[1]=Point(-1e10,1e10);
p[2]=Point(1e10,1e10);
p[3]=Point(1e10,-1e10);
p[4]=Point(-1e10,-1e10);
p[5]=p[1];
ban_tot=4;
for(int i=1;i<=3;i++){
cnt=-1;
for(int j=1;j<=n;j++){
double x1=cam[i].x,y1=cam[i].y,z1=cam[i].z;
double x2=mac[j].x,y2=mac[j].y,z2=mac[j].z;
st[++cnt].x=x1-((x2-x1)/(z2-z1)*z1);
st[cnt].y =y1-((y1-y2)/(z1-z2)*z1);
}
cnt++;
Grahamxy(st,cnt);
int j=0;
for(int k=cnt-1;k>=0;k--){
tp[++j]=st[k];
}
tp[cnt+1]=tp[1];
for(int k=1;k<=cnt;k++) ts[k].s=tp[k],ts[k].e=tp[k+1];
for(int k=1;k<=cnt;k++) CUT(ts[k]);
}
if(ban_tot>=3) {
printf("%.2lf\n",getarea(p,ban_tot));
}
else printf("0.00");
}
return 0;
}