hdu 6055(简单几何、找正方形)

33 篇文章 0 订阅
6 篇文章 0 订阅
/*
    hdu 6055
    题意大体是
    给你一堆点
    点的坐标(x,y)x y都是整数
    问这些点能组成多少个不同的正多边形
    因为x y是整数
    所以能组成的正多边形只能是正方形(这个自己想想吧应该很好懂)
    所以题目就变成问我们正方形有多少个
    我们先枚举两个点
    两个点组成正方形的一条边
    一条边可以确定两个正方形
    那么我们就只要判断那两个正方形剩余的两点
    一开始有没有输入
    最后输出的时候要注意
    枚举点的时候一开始先枚举点a再枚举点b
    与一开始先枚举点b再枚举点a是一样的
    所以ans/2
    又因为一个边算了4次
    所以ans/2/4==ans/8
*/
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <string.h>
#define mod 1000000007
#define MAX 100005
#define ll long long
#define PI acos(-1)
using namespace std;


struct point
{
  int x,y;
}p[505];//存点
int map[405][405];//对输入了点做标记标记,如果输入的是x y,那么map[x][y]=1否则就是0
                  //另外开405的原因是防止数组越界,因为x y在极限情况下会+100然后*2
                  //关于*2是在下面讨论情况的时候可能发生的事(效果是*2,但不是真正有这个操作,这样描述一下而已)
int main()
{
    int n;
    while(cin>>n)
    {
        memset(map,0,sizeof(map));
        for(int i=1;i<=n;i++)
        {
            int x,y;
            cin>>x>>y;
            x+=100;//因为接下来要做标记,x y的范围是-100~100所以我们要把所有的数变成都成正数
            y+=100;//使其范围变成0~200,这样才能存入数组
            p[i].x=x;//存入点的数组
            p[i].y=y;
            map[x][y]=1;//标记
        }
        int ans=0;
        for(int i=1;i<=n;i++)//枚举两个点
        {
           for(int j=i+1;j<=n;j++)
           {
                int x=p[i].x-p[j].x;//算枚举的两个点横坐标只差
                int y=p[i].y-p[j].y;//算枚举的两个点纵坐标只差
                //接下来是通过这两个点推算另外的点的过程
                //一个是推算右上这个四边形,一个是左下
                //关于坐标怎么来的画一个四边形然后用三角形全等可证
                //关于一下为什么是+y -x以及-y +x错开
                //因为上面求的x y不一定是正数
                //有一种情况当x是负数时我们要加上它的绝对值就变成了-x
                //然后把所有的8种情况(四条边每条两种情况)全部列出来,发现这两种表达可以饱览全部情况
                //假设我们把上面的差值都取绝对值的话
                //我们需要分类讨论4种情况(因为情况重复的关系8种变4种)
                //分别为 +x +y,-x -y,+x -y,-x +y
                int a,b,c,d;
                a=p[i].x+y;
                b=p[i].y-x;
                c=p[j].x+y;
                d=p[j].y-x;
                if(a>=0&&b>=0&&c>=0&&d>=0&&map[a][b]&&map[c][d])
                    ans++;
                a=p[i].x-y;
                b=p[i].y+x;
                c=p[j].x-y;
                d=p[j].y+x;
                if(a>=0&&b>=0&&c>=0&&d>=0&&map[a][b]&&map[c][d])
                    ans++;
           }
        }
        cout<<ans/4<<endl;
    }
    return 0;
}
/*


25
0 0
0 1
0 -1
1 0
-1 0
1 1
1 -1
-1 1
-1 -1
-2 3
-1 3
0 3
1 3
2 3
-2 1
2 1
2 0
-2 0
-2 -1
2 -1
-2 -2
-1 -2
0 -2
1 -2
2 -2
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值