1. 程式人生 > >正方形計數問題(窮舉+pair+struct/C++)

正方形計數問題(窮舉+pair+struct/C++)



正方形計數 count
【問題描述】給定平面上N個點,你需要計算以其中4個點為頂點的正方形的個數。
注意:這裡的正方形邊不一定需要和座標軸平行。
【輸入格式】
輸入檔案中僅一行為一個整數N。
接下來的N行,每行有兩個整數xi,yi,分別表示N個點的座標。
【輸出格式】
輸出檔案中僅一行為一個整數,即正方形的個數。
【輸入輸出樣例】
輸入:
7
0 0
0 1
1 0
1 1
1 2
2 1
2 2
輸出:
3
【資料範圍】
對於20%的資料,滿足:1<=N<=20;
對於100%的資料,滿足:1<=N<=500,-50<=X[i],Y[i]<=50,點不會重疊

在一個正方形中,給定兩個節點的座標與它們的相對位置後,另外兩個節點的座標就固定了,我們利用這個性質來進行窮舉,題目資料範圍不大,不會超時,並且程式中使用記憶化機制進行限制。程式碼中的座標用pair陣列和bool陣列進行雙重儲存,程式碼如下

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;

pair<int,int>node[501];
bool vis[501][501];
bool nodesquare[101][101];
int n;

struct dbnode
{
	int x1,y1;
	int x2,y2;
};

dbnode makesquare(int xx1,int yy1,int xx2,int yy2)
{
	int a=xx1-xx2;
	int b=yy2-yy1;
	dbnode ans;
	ans.x1=xx1+b;
	ans.y1=yy1+a;
	ans.x2=xx2+b;
	ans.y2=yy2+a;
	return ans;
}

int find(int x,int y)
{
	for(int i=1;i<=n;i++)
	{
		if (node[i].first==x && node[i].second==y) return i;
	}
}

int main()
{
	cin >> n;
	int x,y,i,j;
	memset(nodesquare,0,sizeof(nodesquare));
	for(i=1;i<=n;i++)
	{
		cin >> x >> y;
		node[i]=make_pair(x+50,y+50);
		nodesquare[x+50][y+50]=1;
	}
	memset(vis,0,sizeof(vis));
	dbnode k;
	int p,p1,ans=0;
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=n;j++)
		{
			if (i==j || vis[i][j]==1) continue;
			vis[i][j]=vis[j][i]=1;
			k=makesquare(node[i].first,node[i].second,node[j].first,node[j].second);
			if (nodesquare[k.x1][k.y1])
			{
				p=find(k.x1,k.y1);
				vis[p][i]=vis[i][p]=vis[p][j]=vis[j][p]=1;
			}
			if (nodesquare[k.x2][k.y2])
			{
				p1=find(k.x2,k.y2);
				vis[p1][i]=vis[i][p1]=vis[p1][j]=vis[j][p1]=1;
			}
			if (nodesquare[k.x1][k.y1] && nodesquare[k.x2][k.y2])
			{
				vis[p][p1]=vis[p1][p]=1;
				ans++;
			}
		}
	}
	cout << ans << endl;
	return 0;
}