POJ 1408

题意:给一个1*1的正方形,然后每条边上有n个点,按照一定规律连线把矩形切成(n+1)^2个小四边形(方式不好描述,直接看题吧),求这里面面积最大的小四边形。

题解:求四边形面积可以直接用叉积公式,然后用两个扫描线,记录相邻的两条线上组成四边形的所有的点,计算之后,靠右的扫描线变成新的扫描线组的左边的线。

View Code
 1 #include<cstdlib>

 2 #include<cmath>

 3 #include<cstdio>

 4 #include<algorithm>

 5 #define max(a,b) (((a)>(b))?(a):(b))

 6 #define min(a,b) (((a)>(b))?(b):(a))

 7 #define sign(x) ((x)>eps?1:((x)<-eps?(-1):(0))) //符号函数

 8 using namespace std;

 9 const int MAXN=1000;

10 const double eps=1e-8,inf=1e50;

11 struct point

12 {

13     double x,y;

14     point(){}

15     point(double _x,double _y){x=_x;y=_y;}

16 };

17 struct line

18 {

19     point a,b;

20     line(){}

21     line(point _a,point _b){a=_a;b=_b;}

22 };

23 inline double xmult(point o,point a,point b)

24 {

25     return (a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y);

26 }

27 inline double xmult(double x1,double y1,double x2,double y2)

28 {

29     return x1*y2-x2*y1;

30 }

31 inline double dmult(point o,point a,point b)

32 {

33     return (a.x-o.x)*(b.x-o.x)+(a.y-o.y)*(b.y-o.y);

34 }

35 point line_intersection(line u,line v)

36 {

37     double a1=u.b.y-u.a.y,b1=u.a.x-u.b.x;

38     double c1=u.b.y*(-b1)-u.b.x*a1;

39     double a2=v.b.y-v.a.y,b2=v.a.x-v.b.x;

40     double c2=v.b.y*(-b2)-v.b.x*a2;

41     double D=xmult(a1,b1,a2,b2);

42     return point(xmult(b1,c1,b2,c2)/D,xmult(c1,a1,c2,a2)/D);

43 }

44 inline double getarea(point pg[],int n)

45 {

46     double area=0;

47     pg[n]=pg[0];

48     for(int i=0;i<n;i++)

49         area+=xmult(pg[i].x,pg[i].y,pg[i+1].x,pg[i+1].y);

50     return fabs(area)/2.0;

51 }

52 line li[2][50];

53 point po[2][50],res[4][50];

54 int main()

55 {

56     int n;

57     while(scanf("%d",&n)!=EOF&&n)

58     {

59         double ans=0;

60         for(int i=0;i<n;i++)

61             scanf("%lf",&res[0][i].x),res[0][i].y=0.0;

62         for(int i=0;i<n;i++)

63             scanf("%lf",&res[1][i].x),res[1][i].y=1.0,li[0][i]=line(res[0][i],res[1][i]);

64         for(int i=0;i<n;i++)

65             scanf("%lf",&res[2][i].y),res[2][i].x=0.0,po[0][i+1]=res[2][i];

66         for(int i=0;i<n;i++)

67             scanf("%lf",&res[3][i].y),res[3][i].x=1.0,li[1][i]=line(res[2][i],res[3][i]);

68         po[0][0]=point(0.0,0.0);

69         po[0][n+1]=point(0.0,1.0);

70         for(int i=0;i<n;i++)

71         {

72             int a=i&1,b=a^1;

73             for(int j=0;j<n;j++)

74                 po[b][j+1]=line_intersection(li[1][j],li[0][i]);

75             po[b][0]=res[0][i];

76             po[b][n+1]=res[1][i];

77             for(int j=0;j<=n;j++)

78             {

79                 point temp[6]={po[a][j],po[a][j+1],po[b][j+1],po[b][j]};

80                 ans=max(ans,getarea(temp,4));

81             }

82         }

83         int a=n&1,b=a^1;

84         for(int j=0;j<n;j++)

85             po[b][j+1]=res[3][j];

86         po[b][0]=point(1.0,0.0);

87         po[b][n+1]=point(1.0,1.0);

88         for(int j=0;j<=n;j++)

89         {

90             point temp[4]={po[a][j],po[a][j+1],po[b][j+1],po[b][j]};

91             ans=max(ans,getarea(temp,4));

92         }

93         printf("%.6lf\n",ans);

94     }

95     return 0;

96 }

你可能感兴趣的:(poj)