POJ 1408[Fishnet]题解

本博客解析POJ 1408[Fishnet]问题,探讨如何在1*1正方形中,通过2n条线连接4n个点,找到所有小四边形中面积最大的。解题思路涉及平面几何,通过计算交点和使用点积求解最大面积。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目梗概

给你一个大小为1*1的正方形,正方形的每条边都有n个点,现在用2n条线用类似于下图的方法将这4n个点连接起来,求构成的所有单个小四边形中面积最大的那个的面积。 (传送门
这里写图片描述


解题思路

这是道平面几何的基础题,首先先将所有的线两两相交并求出所有交点,然后将每个小四边形拆成两个三角形,这要就可以直接用点积来求出小四边形面积,边算边刷max。真的就是道基础题。(真相是感觉再也bb下去了,所以只有这些),各种细节还是看代码比较有效果。

#include<cstdio>
using namespace std;
int n;
double ans;
struct data
{
  double x,y;
  data(double x=0,double y=0):x(x),y(y){ }
}fn[35][35];
data operator + (const data a,const data b){return data(a.x+b.x,a.y+b.y);}
data operator - (const data a,const data b){return data(a.x-b.x,a.y-b.y);}
data operator * (const data a,double b){return data(a.x*b,a.y*b);}
double cross(const data a,const data b) {return a.x*b.y-a.y*b.x;}
double absf(double x)
{
  return (x>0)?x:-x;
}
data getp(data a,data b,data c,data d)
{
  double t=cross(d,a-c)/cross(b,d);
  return a+b*t;
}
double getS(data a,data b,data c,data d)
{
  return (absf(cross(b-c,d-c))+absf(cross(b-a,c-a)))/2;
}
void _init()
{
  n++; double x;
  fn[0][0]=data(0.0,0.0);
  fn[0][n]=data(1.0,0.0);
  fn[n][0]=data(0.0,1.0);
  fn[n][n]=data(1.0,1.0);
  for (int i=1;i<n;i++){scanf("%lf",&x); fn[0][i]=data(x,0.0);}
  for (int i=1;i<n;i++){scanf("%lf",&x); fn[n][i]=data(x,1.0);}
  for (int i=1;i<n;i++){scanf("%lf",&x); fn[i][0]=data(0.0,x);}
  for (int i=1;i<n;i++){scanf("%lf",&x); fn[i][n]=data(1.0,x);}
  for (int i=1;i<n;i++)
    for (int j=1;j<n;j++)
      fn[i][j]=getp(fn[i][0],fn[i][n]-fn[i][0],fn[0][j],fn[n][j]-fn[0][j]);
}
void _solve()
{
  ans=0.0;
  for (int i=0;i<=n;i++)
  for (int i=0;i<n;i++)
    for (int j=0;j<n;j++)
    {
      double x=getS(fn[i][j],fn[i+1][j],fn[i][j+1],fn[i+1][j+1]);
      if (ans<x) ans=x;
    }
  printf("%0.6lf\n",ans);
}
int main()
{
  freopen("fishnet.in","r",stdin);
  freopen("fishnet.out","w",stdout);
  scanf("%d",&n);
  while (n)
  {
    _init();
    _solve();
    scanf("%d",&n);
  }
  return 0;
}

每日一句:
Orz zzkksunboy大佬

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值