hdu6055Regular polygon(暴力枚举)

31 篇文章 0 订阅
14 篇文章 0 订阅

Regular polygon

 

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1808    Accepted Submission(s): 709

 

 

Problem Description

On a two-dimensional plane, give you n integer points. Your task is to figure out how many different regular polygon these points can make.

 

 

Input

The input file consists of several test cases. Each case the first line is a numbers N (N <= 500). The next N lines ,each line contain two number Xi and Yi(-100 <= xi,yi <= 100), means the points’ position.(the data assures no two points share the same position.)

 

 

Output

For each case, output a number means how many different regular polygon these points can make.

 

 

Sample Input

 

4 0 0 0 1 1 0 1 1 6 0 0 0 1 1 0 1 1 2 0 2 1

 

 

Sample Output

 

1
2

 

本身是一道水题,但做这种水题我脑子很容易一下抽,WA了10几次

题意:

给你n个点,求出这n个点能组成多少个不同的正多边形

解析:

因为坐标都是整数,而在边数>=4的多边形中肯定至少存在一条斜的边,所以这样点的坐标一定不是整数了,因此该正多边形一定是正方形。(详细证明网上好像说某个国家队的大神写过一篇论文证明过)

接下来就是暴力枚举,先选定两个点,再根据这两个点算出可以组成正方形的另外两个点,再判定另外两个点是否存在即可

 

当时WA了这么多次的原因是判定条件写错了抓狂。找正方形的时候其实有两种情况一种是斜向右下的边,此时另外两个点又有两种情况是一种是x+,y+(在边的上方),另一种是x-,y-(在边的下方),还有一种是斜向左下的边此时两种情况是1.x-,y+(在边的上方) 2.x+,y-(在边的下方)

就是这两情况判定条件是横坐标之差的+-以及纵坐标之差的+-

但我的判定条件竟然是前一种不满足的话就后一种,这样肯定会有边是后一种情况不满足的,但在一开始在前一种情况计算中满足了情况,这样就多加了

 

 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 3000
using namespace std;
typedef struct Point
{
    int x,y;
}Point;
Point loca[MAXN];
int map[MAXN][MAXN];

int cmp(Point a,Point b)
{
    if(a.y==b.y)
        return a.x<b.x;
    return a.y<b.y;

}

bool judge(Point a,Point b)
{
    if(a.x>=0&&b.x>=0&&a.y>=0&&b.y>=0&&map[a.x][a.y]==1&&map[b.x][b.y]==1)
    {
        return true;
    }
    return false;
}


int main()
{
    int n,ans;
    while(scanf("%d",&n)!=EOF)
    {
    ans=0;
    memset(map,0,sizeof(map));
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&loca[i].x,&loca[i].y);
        loca[i].x+=100;
        loca[i].y+=100;
        map[loca[i].x][loca[i].y]=1;
    }

    sort(loca,loca+n,cmp);



    for(int i=0;i<n;i++)
    {
        for(int j=i+1;j<n;j++)
        {
			int xx=loca[i].x-loca[j].x;
			int yy=loca[i].y-loca[j].y;
            Point a,b,c,d;
			if(xx>=0&&yy<=0)
			{
			xx=abs(xx);
			yy=abs(yy);
            a.x=loca[i].x+yy;
            a.y=loca[i].y+xx;
            b.x=loca[j].x+yy;
            b.y=loca[j].y+xx;
            if(judge(a,b))  
            {
                ans++;
               // flag=1;
            }

            c.x=loca[i].x-yy;
            c.y=loca[i].y-xx;
            d.x=loca[j].x-yy;
            d.y=loca[j].y-xx;
            if(judge(c,d))
            {
                ans++;
                //flag=1;
            }
			}
			else
            {
				xx=abs(xx);
				yy=abs(yy);
                a.x=loca[i].x-yy;
                a.y=loca[i].y+xx;
                b.x=loca[j].x-yy;
                b.y=loca[j].y+xx;
                if(judge(a,b))  
                {
                    ans++;
                    //flag=1;
                }
                
                c.x=loca[i].x+yy;
                c.y=loca[i].y-xx;
                d.x=loca[j].x+yy;
                d.y=loca[j].y-xx;
                if(judge(c,d))
                {
                    ans++;
                    //flag=1;
                }
            }
            
            


            
        }
    }
	//printf("%d\n",ans);
    printf("%d\n",ans/4);
    }
    return 0;
}

 

 

 

在网上看了代码后发现其实并不用那么麻烦来分情况。。。

 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 3000
using namespace std;
typedef struct Point
{
	int x,y;
}Point;
Point loca[MAXN];
int map[MAXN][MAXN];
//int rowloca[300];

int cmp(Point a,Point b)
{
	if(a.y==b.y)
		return a.x<b.x;
	return a.y<b.y;

}

bool judge(Point a,Point b)
{
	if(a.x>=0&&b.x>=0&&a.y>=0&&b.y>=0&&map[a.x][a.y]==1&&map[b.x][b.y]==1)
	{
		return true;
	}
	return false;
}


int main()
{
	int n,ans;
	while(scanf("%d",&n)!=EOF)
	{
	ans=0;
	memset(map,0,sizeof(map));
	for(int i=0;i<n;i++)
	{
		scanf("%d%d",&loca[i].x,&loca[i].y);
		loca[i].x+=100;
		loca[i].y+=100;
		map[loca[i].x][loca[i].y]=1;
	}

	sort(loca,loca+n,cmp);

	for(int i=0;i<n;i++)
	{
		for(int j=i+1;j<n;j++)
		{
			
			Point a,b;
			int xx=loca[i].x-loca[j].x;
			int yy=loca[i].y-loca[j].y;
			a.x=loca[i].x-yy;
			a.y=loca[i].y+xx;
			b.x=loca[j].x-yy;
			b.y=loca[j].y+xx;
			if(judge(a,b))  
			{
				ans++;
			}

			Point c,d;
			c.x=loca[i].x+yy;
			c.y=loca[i].y-xx;
			d.x=loca[j].x+yy;
			d.y=loca[j].y-xx;
			if(judge(c,d))
			{
				ans++;
			}


			
		}
	}
	printf("%d\n",ans/4);
	}
	return 0;
}

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值