POJ 1314 Finding Rectangles

Description

Consider the point sets in figures 1a, 2a, and 3a. Using only those points as vertices, figures 1b, 2b, and 3b show all the rectangles that can be formed with horizontal and vertical sides. No rectangles can be formed from the points in figure 4. 

Your task is to write a program that can find all rectangles that can be formed from a given set of points. The example input and output given below correspond to the figures above. 




Input

The input contains one or more point sets, followed by a line containing the number 0 that signals the end of the file. Each point set begins with a line containing n, the number of points, and is followed by n lines that describe the points. Each point description contains a capital letter that is the label of the point, then a space, the horizontal coordinate, a space, and the vertical coordinate. Within each set, points labels occur in alphabetical order. Note that since each point is labelled with a capital letter there can be at most 26 points. All coordinates are nonnegative integers less than 50. Points within a set are unique.

Output

The output for each point set starts with "Point set ", followed by the number of the point set and a colon. If there are no rectangles, " No rectangles" appears after the colon. If there are rectangles, they are listed starting on the next line. A blank precedes each rectangle. Each rectangle is given by its vertex labels, in clockwise order from the upper left, so the order is upper left, upper right, lower right, lower left. The rectangles are listed ten per line, except for the last line, where there may be as few as one. The rectangles are listed in alphabetical order.

Sample Input

7
A 1 1
B 2 1
C 3 1
D 2 3
E 3 3
F 1 4
G 3 4
8
B 1 1
D 2 1
F 4 1
J 4 4
L 2 4
M 2 3
N 4 3
P 1 2
12
A 1 5
B 2 5
C 1 4
D 2 4
E 1 3
F 2 3
G 1 2
H 2 2
I 1 1
J 2 1
K 1 0
L 2 0
5
B 1 1
D 2 1
L 2 4
N 2 3
P 1 2
0

Sample Output

Point set 1:
 DECB FGCA
Point set 2:
 LJFD LJNM MNFD
Point set 3:
 ABDC ABFE ABHG ABJI ABLK CDFE CDHG CDJI CDLK EFHG
 EFJI EFLK GHJI GHLK IJLK
Point set 4: No rectangles                                                                        
题目链接:http://poj.org/problem?id=1314
题意:输入n个点的坐标和符号,点的符号用大写字母来表示,以字典序输出这些点构成的长方形,长方形按照
左上角->右上角->右下角->左下角来确定。输入最多26个点,每个点的坐标都在第一象限且坐标的大小不超过50。
解题思路
准备:构造一个存储输入点信息(坐标,符号)的结构体,因为每个点的坐标都在第一象限且不超过50,
所以定义一个字符型的二维数组来存储每个点的符号,初始化为空字符'\0',每当输入一个点后,就把该点的符号改为输入的符号
解题:将每个点作为长方形左上角的点进行遍历,这样避免了重复计算也满足题目长方形的要求,接着找到右上角的点再枚举剩下的
两个点。将长方形的名字存入字符串数组,使用sort排序后输出即可。
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int NUM = 10000;//能得到长方形的最大个数
struct Point{
	char name;//名字
	int x,y;//坐标
};
string rec[NUM];//记录每个长方形名字的字符串数组
Point point[30];
char exist[50][50];//第一象限内不大于50的所有点 
int n;//输入的点的个数 
void solve()
{
	int i,j,k,l;
	int x,y;
	string name;//记录长方形
	for(i=0,l=0;i<n;i++)//将每个点作为左上角的点遍历一次
	{
		name=point[i].name;
		x=point[i].x;
		y=point[i].y;
		for(j=x+1;j<50;j++)//确定一个右上角的点
		{
			if(exist[j][y]!='\0')
			{
				name+=exist[j][y];
				for(k=y-1;k>=0;k--)//枚举剩下的两个点(右下角和左下角) 
				{
					if(exist[j][k]!='\0' && exist[x][k]!='\0')
					{
						name+=exist[j][k];
						name+=exist[x][k];
						rec[l++]=name;//将得到的长方形存入字符串数组中
						name=point[i].name;
						name+=exist[j][y];
					}
				}
				name=point[i].name;
			}
		}
	}
	if(l==0)//如果长方形字符数组长度为零,则说明不存在长方形
	{
		cout<<" No rectangles"<<"\n";
		return;
	}
 	sort(rec,rec+l);//将得到的长方形的名字按字典序排序
	cout<<"\n";
	for(i=1;i<=l;i++)
	{
		if(i!=1&&i%10==1) cout<<"\n";//十个一行
		cout<<" "<<rec[i-1];
	}
	cout<<"\n";
}
int main(void)
{
	int kase=0;//测试组数 
	cin>>n;
	while(n)//n为0时结束输入
	{
		memset(exist,'\0',sizeof(exist));//初始化每个点的名字为空
		for(int i=0;i<n;i++)
		{
			getchar();
			cin>>point[i].name>>point[i].x>>point[i].y; //输入每个点的信息
			exist[point[i].x][point[i].y]=point[i].name;//将输入的点的名字修改
		}
		printf("Point set %d:",++kase);
		solve();
		cin>>n;
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值