BZOJ2338: [HNOI2011]数矩形

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2338

中学数学老师告诉我们,一个矩形的两条对角线相等,所以只要把所有的边拿出来,记录下中点坐标及长度,然后排一遍序扫一遍更新答案。。(听说开double会炸?

#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<queue>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define down(i,l,r) for (int i=l;i>=r;i--)
#define clr(x,y) memset(x,y,sizeof(x))
#define maxn 1505
#define inf int(1e9)
#define eps 1e-6
using namespace std;
typedef long long ll;
struct data{ll len,x,y;int a,b;
}a[maxn*maxn];
struct node{ll x,y;
};
int n,cnt,next,now;
ll ans,x[maxn],y[maxn];
ll read(){
    ll x=0,f=1; char ch=getchar();
    while (!isdigit(ch)) {if (ch==‘-‘) f=-1; ch=getchar();}
    while (isdigit(ch)) {x=x*10+ch-‘0‘; ch=getchar();}
    return x*f;
}
ll sqr(ll x){
    return x*x;
}
ll dis(int a,int b){
    return sqr(x[a]-x[b])+sqr(y[a]-y[b]);
}
bool cmp(data a,data b){
    if (a.x==b.x&&a.len==b.len) return a.y<b.y;
    else if (a.len==b.len) return a.x<b.x;
    return a.len<b.len;
}
bool jud(data a,data b){
    if (a.x==b.x&&a.y==b.y&&a.len==b.len) return 1;
    return 0;
}
ll cross(node p,node q){
    return abs(p.x*q.y-p.y*q.x);
}
void solve(data a,data b){
    node p=(node){x[a.a]-x[a.b],y[a.a]-y[a.b]};
    node q=(node){x[a.a]-x[b.a],y[a.a]-y[b.a]};
    ans=max(ans,cross(p,q));
}
int main(){
    scanf("%d",&n);
    rep(i,1,n){
        x[i]=read(); y[i]=read();
    }
    rep(i,1,n) rep(j,i+1,n) a[++cnt]=(data){dis(i,j),x[i]+x[j],y[i]+y[j],i,j};
    sort(a+1,a+1+cnt,cmp);
    now=cnt;
    while (now>1){
        next=now-1;
        while (jud(a[now],a[next])) {
            solve(a[now],a[next]);
            next--;
        }
        now--;
    }
    printf("%lld\n",ans);
    return 0;
}
时间: 2024-10-12 13:05:44

BZOJ2338: [HNOI2011]数矩形的相关文章

【计算几何】bzoj2338 [HNOI2011]数矩形

对于两条线段,若其中点重合,且长度相等,那么它们一定是某个矩形的对角线. N*N地处理出所有线段,排序,对每一部分中点重合.长度相等的线段进行暴力枚举,更新答案. 用 long double 注意EPS的设置,卡精度. 注意数组大小的设置,容易MLE. 1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 #include<iostream> 5 using namespace std; 6

【BZOJ2338】[HNOI2011]数矩形 几何

[BZOJ2338][HNOI2011]数矩形 题解:比较直观的做法就是枚举对角线,两个对角线能构成矩形当且仅当它们的长度和中点相同,然后用到结论:n个点构成的矩形不超过n^2.5个(不会证),所以两两枚举对角线即可. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll;

bzoj-2338 2338: [HNOI2011]数矩形(计算几何)

题目链接: 2338: [HNOI2011]数矩形 Time Limit: 20 Sec  Memory Limit: 128 MB Description Input Output 题意: 思路: 求最大的矩形面积,先把这些点转化成线段,记录下线段的长度和中点和两个端点,形成矩形说明对角线长度相等,且共中点,所以把线段按长度和中点排序,如果都相等,然后用三角形的三个顶点坐标计算面积的公式计算最大面积就好了; AC代码: /************************************

BZOJ 2338 HNOI2011 数矩形 计算几何

题目大意:给定n个点,求一个最大的矩形,该矩形的四个顶点在给定的点上 找矩形的方法是记录所有线段 若两条线段长度相等且中点重合 这两条线段就可以成为矩形的对角线 于是我们找到所有n*(n-1)/2条线段,按长度排序,长度相等按照中点排序,然后对于每个点向前找符合要求的,计算面积,更新ans 注意避免一切double!长度切记不能开根号,直接用long long存储,否则第三个点有两条长度极其接近的线段把double卡掉,计算面积要用叉积,中点不要除以2,连math库都不用开了! #include

数矩形(N - 暴力求解、打表)

数矩形 Description 给你一个高为n ,宽为m列的网格,计算出这个网格中有多少个矩形,下图为高为2,宽为4的网格. Input 第一行输入一个t, 表示有t组数据,然后每行输入n,m,分别表示网格的高和宽 ( n < 100 , m < 100). Output 每行输出网格中有多少个矩形. Sample Input 2 1 2 2 4 Sample Output 3 30 题意: 一个N*M的网格,计算有多少矩形? 分析: 数学问题. 用到暴力,和打表的方法.打表就是找规律然后直接

bzoj2338 数矩形

给出N(N≤1500)个点,求选四个点作为顶点组成矩形的最大面积,保证有解. 对每两个点连边,按边长排序,枚举等长且中点相同的边作为对角线组成矩形,计算面积取最大值. 时间复杂度O(n2logn) #include<cstdio> #include<algorithm> int xs[1600],ys[1600]; long long ans=0; struct edge{ int x1,y1,x2,y2; long long len; int xm,ym; void cal(){

BZOJ 2338 HNOI 2011 数矩形 计算几何

题目大意:给出平面上的一些点,求这些点中组成的矩形的最大面积. 思路:任意找四个点然后判断肯定是不行的,那么我们不妨来想一想矩形的性质.比如,对角线的交点是两条对角线的中点,对角线相等.这样的话只要找到一对线段,使得他们的中点相同,并且长度相同,那么这两个对角线一定能够组成一个矩形.只有就可以利用叉积求出面积了. 比较坑的一点是,这个题万万不能用double,因为有一个点专门卡double.可以尝试用long double,最好还是避免精度问题,统一用整数. CODE: #include <cs

屯题计划

感觉lxt一天到晚就是在浪啊浪, 毫无斗志, 颓废得不得了, 每天看小说玩手机到三四点然后整个人都是乱七八糟的. 不行不行我要振作起来了! 从最开始学语言到现在都快两年过去了 T T , 代码能力还是渣成这样简直不能看 T T 觉得应该学学zj爷们屯题. 加油! (题目是直接从劼很久以前的几篇屯题计划里边搬过来的我之前做过的题就删掉了 [BZOJ1822][JSOI2010]Frozen Nova 冷冻波 很水的网络流加计算几何, 然而计算几何部分非常莫名奇妙, 题目应该是判断一个圆是否与一个线

2013.21.A

随便点了一套刷,这套质量挺棒的,学了不少的东西,并且碰到了很久都没有打的题目//很久没有刷一套题了吧,最近发生的东西实在可怕到我都难以接受了....clam down clam dowm 先管好自己的事再说吧~1.card + ? 题1  集卡片 [问题描述] lzh小时候很喜欢收集卡片,他经常要去商店购买新到的卡片. 商店出售的卡片有N张,是连续的,并且都连在一起成为一个长串,商店阿姨告诉lzh只能购买连续的一段,这一串卡片共有M种,每种卡片都有一个价格,lzh拿的钱数为V,他想花最少的钱来集