puk1408(fishnet)

一道很基本的计算几何题,通常被大牛们称之为水题!

题意是:在以(0,0)为左下点及以(1,1)为右上点的一个正方形上,在平行的边上有相应的点构成一条直线,与其它直线有相应的交点,这些交点会把整个区域分成若干个四边形,求面积最大的.

思想是:利用叉积求出各交点,再利用求多边形面积的方法枚举每个四边形,保留最大的即可.

源代码如下:

#include<iostream>
#include<cstdlib>
using namespace std;
struct point
{
 double x,y;
};
struct line
{
 point a,b;
};
struct map
{
 point col[34];
};
map row[34];
line li1[31],li2[31];
int len;
int n;
double polygonarea(point *polygon,int N)
{
    int i,j;
    double area = 0;
    for (i=0;i<N;i++) {
        j = (i + 1) % N;
        area += polygon[i].x * polygon[j].y;
        area -= polygon[i].y * polygon[j].x;
 }
    area /= 2;
    return(area < 0 ? -area : area);
}
point intersection(line u,line v){
 point ret=u.a;
 double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))
  /((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));
 ret.x+=(u.b.x-u.a.x)*t;
 ret.y+=(u.b.y-u.a.y)*t;
 return ret;
}
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;
}
void product_point()
{
 int i,j;
 for(i=1;i<=n;i++)
 {
  for(j=1;j<=n;j++)
  {
   row[i].col[j]=intersection(li2[i-1].a,li2[i-1].b,li1[j-1].a,li1[j-1].b);
  }
 }
}
void count_area()
{
 int i,j;
 point p[5];
 double max_area=0.0,temp;
 for(i=0;i<len;i++)
 {
  for(j=0;j<len;j++)
  {
   p[0]=row[i].col[j];
   p[1]=row[i].col[j+1];
   p[2]=row[i+1].col[j+1];
   p[3]=row[i+1].col[j];
   temp=polygonarea(p,4);
   if(temp>max_area)
    max_area=temp;
  }
 }
 printf("%.6lf/n",max_area);
}
int main()
{
 int i,j;
 while(cin>>n&&n)
 {
  row[0].col[0].x=0;
  row[0].col[0].y=0;
  row[0].col[n+1].x=1;
  row[0].col[n+1].y=0;
  row[n+1].col[0].x=0;
  row[n+1].col[0].y=1;
  row[n+1].col[n+1].x=1;
  row[n+1].col[n+1].y=1;
  len=n+1;
  i=0;
  for(j=0;j<n;j++)
  {
   cin>>li1[j].a.x;
   li1[j].a.y=0;
   row[i].col[j+1]=li1[j].a;
  }
  for(j=0;j<n;j++)
  {
   cin>>li1[j].b.x;
   li1[j].b.y=1;
   row[n+1].col[j+1]=li1[j].b;
  }
  i++;
  for(j=0;j<n;j++)
  {
   cin>>li2[j].a.y;
   li2[j].a.x=0;
   row[j+1].col[0]=li2[j].a;
  }
  for(j=0;j<n;j++)
  {
   cin>>li2[j].b.y;
   li2[j].b.x=1;
   row[j+1].col[n+1]=li2[j].b;
  }
  product_point();
  count_area();
 }
 return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值