BZOJ 2338 HNOI 2011 数矩形 计算几何

题目大意:给出平面上的一些点,求这些点中组成的矩形的最大面积。

思路:任意找四个点然后判断肯定是不行的,那么我们不妨来想一想矩形的性质。比如,对角线的交点是两条对角线的中点,对角线相等。这样的话只要找到一对线段,使得他们的中点相同,并且长度相同,那么这两个对角线一定能够组成一个矩形。只有就可以利用叉积求出面积了。

比较坑的一点是,这个题万万不能用double,因为有一个点专门卡double。可以尝试用long double,最好还是避免精度问题,统一用整数。

CODE:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 1600
using namespace std;

struct Point{
    long long x,y;

    Point(long long _ = 0,long long __ = 0):x(_),y(__) {}
    bool operator <(const Point &a)const {
        if(x == a.x)    return y < a.y;
        return x < a.x;
    }
    Point operator -(const Point &a)const {
        return Point(x - a.x,y - a.y);
    }
    bool operator ==(const Point &a)const {
        return (x == a.x && y == a.y);
    }
    void Read() {
        scanf("%lld%lld",&x,&y);
    }
}point[MAX];
struct Segment{
    Point a,b;
    Point bi_mid;
    long long length;

    Segment(Point _,Point __):a(_),b(__) {
        Point temp = a - b;
        length = temp.x * temp.x + temp.y * temp.y;
        bi_mid.x = a.x + b.x;
        bi_mid.y = a.y + b.y;
    }
    Segment() {}
    bool operator <(const Segment &a)const {
        if(length == a.length)  return bi_mid < a.bi_mid;
        return length < a.length;
    }
}segment[MAX * MAX >> 1];

int points,segments;

inline long long Cross(const Point &a,const Point &b);
inline long long Work(const Segment &a,const Segment &b);

int main()
{
    cin >> points;
    for(int i = 1;i <= points; ++i)
        point[i].Read();
    for(int i = 1;i <= points; ++i)
        for(int j = i + 1;j <= points; ++j)
            segment[++segments] = Segment(point[i],point[j]);
    sort(segment + 1,segment + segments + 1);
    long long ans = 0;
    for(int i = 1;i <= segments; ++i) {
        int start = i,end = i;
        while(segment[end + 1].length == segment[start].length && segment[end + 1].bi_mid == segment[start].bi_mid)
            ++end;
        for(int j = start;j <= end; ++j)
            for(int k = j + 1;k <= end; ++k)
                ans = max(ans,Work(segment[j],segment[k]));
        i = end;
    }
    cout << ans << endl;
    return 0;
}

inline long long Cross(const Point &a,const Point &b)
{
    return a.x * b.y - a.y * b.x;
}

inline long long Work(const Segment &a,const Segment &b)
{
    Point p1 = b.a - a.a,p2 = b.b - a.a;
    return abs(Cross(p1,p2));
}

时间: 2024-10-29 04:47:52

BZOJ 2338 HNOI 2011 数矩形 计算几何的相关文章

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

BZOJ 1185 HNOI 2007 最小矩形覆盖 旋转卡壳

题目大意:给出平面上的一些点,问面积最小的矩形满足覆盖所有的点. 思路:覆盖问题和不是凸包上的点没关系,先做凸包.根据贪心的思想,这个覆盖了所有点的矩形肯定至少有一条边与凸包上的边重合,那么我们枚举凸包上的每一条边,对于这个已经确定了一条边的矩形,不难确定其他三个边.注意到已知当前直线的向量,就可以求出两侧和对面的向量,而这三个向量随着枚举的边的移动是单调的,所以就可以用旋转卡壳来卡住剩下的三条边. 但是旋转卡壳时的初值会出问题,如果按照逆时针的顺序求出剩下的三条边的时候,要想通过向量直接卡第三

BZOJ 2326 HNOI 2011 数学作业 矩阵乘法

题目大意 求一个这样的数:"12345678910111213--"对m取模的值. 思路 观察这个数字的特点,每次向后面添加一个数.也就是原来的数乘10^k之后在加上一个数.而且处理每个数量级的时候是相似的.所以就可以用矩阵乘法来加速.我构造的矩阵是这样的. [当前数字累加数字1]×???数量级10011001???=[新的数字累加数字+11] CODE #include <cstdio> #include <cstring> #include <iost

BZOJ 2329 HNOI 2011 括号修复 Splay维护最大连续子段和

题目大意:给出一个括号序列,问一段区间最少需要修改多少括号使得这一段括号变成一段完整的括号序列. 思路:题解见http://ydcydcy1.blog.163.com/blog/static/2160890402013116111134791/ OTZ ydc 维护起来稍微有些麻烦啊.. CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #d

[BZOJ 2326][HNOI 2011]数学作业(矩阵快速幂)

蒟蒻线性代数太烂了...这个逼题居然卡了半天才做出来,弱的不行啊... 矩阵快速幂,把n这个len位数拆成len次分段快速幂就可以了. 注意取模的数字m<=1e9,所以矩阵乘法运算时要先对乘数取模,防止中间运算结果太大溢出,坑爹啊 代码: #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #d

BZOJ 2433 智能车比赛(计算几何+最短路)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2433 题意:若干个矩形排成一排(同一个x之上最多有一个矩形),矩形i和i+1相邻.给定两点S和T,两点均在矩形内.求S到T的最短路径.只能在矩形内部走. 思路:首先,S到T若有转弯,必定是在矩形 的顶点处转弯.因此,只要建立任意两可达顶点(包含S和T)之间距离求最短路即可.若暴力枚举任意两点再判是否可达复杂度O(n^3).优化.枚举起点 a,从左向右扫遍矩形,利用叉积维护关于该点a的上

[BZOJ 2299][HAOI 2011]向量 题解(裴蜀定理)

[BZOJ 2299][HAOI 2011]向量 Description 给你一对数a,b,你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), (-b,a), (-b,-a)这些向量,问你能不能拼出另一个向量(x,y). 说明:这里的拼就是使得你选出的向量之和为(x,y) Input 第一行数组组数t,(t<=50000) 接下来t行每行四个整数a,b,x,y (-2109<=a,b,x,y<=2109) Output t行每行为Y

cogs 1901. [国家集训队2011]数颜色

Cogs 1901. [国家集训队2011]数颜色 ★★★   输入文件:nt2011_color.in   输出文件:nt2011_color.out   简单对比时间限制:0.6 s   内存限制:512 MB [试题来源] 2011中国国家集训队命题答辩 [问题描述] 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令:1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔.2. R P Col 把第P支画笔替换为