1397. 寻找星座

1397. 寻找星座

题目描述
现在你在一张卫星图片中寻找星座,已知该星座在图片中正好出现一次,而且形状一样,方向一样,大小也一样。注意图片中可能有一些与该星座无关的星星。

例如图1中的星座出现在图2的卫星图片中(用圆圈标识部分)。图1中给定的星座需要在X轴上平移2个单位同时在y轴上平移-3个单位才能与卫星图片中的卫星正好吻合。 写一个程序,计算给定星座的星星需要在X和Y方向上分别平移多少单位才能与卫星图片吻合。
在这里插入图片描述
输入
第1行:一个整数M,表示需要寻找的星座中星星的数量;

第2…M+1行:每行两个用空格隔开的整数表示这M个星星的坐标;

第M+2行:一个整数N,表示卫星图片中星星的数量。

第M+3…M+N+2行:每行两个整数表示图片中星星的坐标。 注意:星座和卫星图片中任意两个星星都不重叠;1<=M<=200,1<=N<=1000,X,Y坐标值范围为0…1000000。

输出
输出一行,两个用空格隔开的整数dx,dy,表示需要在X,Y方向上平移的单位。

样例输入
样例输入1:

5
8 5
6 4
4 3
7 10
0 10
10
10 5
2 7
9 7
8 10
10 2
1 2
8 1
6 7
6 0
0 9

样例输入2:

5
904207 809784
845370 244806
499091 59863
638406 182509
435076 362268
10
757559 866424
114810 239537
519926 989458
461089 424480
674361 448440
81851 150384
459107 795405
299682 6700
254125 362183
50795 541942

样例输出
样例输出1:

2 -3

样例输出2:

-384281 179674

思路:
我们先求出在星座中每两个相邻的星星的相对距离(dx[i],dy[i])。当然我们要对星座和卫星图做一次排序(以x为第一关键字(从小到大),以y为第二关键字(从小到大))。

接下来我们枚举卫星图的每颗星星作为星座第一颗,以dx[],dy[]作为搜索条件,去判断是否能找到一个相吻合的星座。在深搜的过程中,可以做一个剪枝:只要当前两颗星星的相对的x距离大于dx[],跳出!

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=2147483647;
const int N=1e6;
struct node
{
	int x,y;
} p[1010],p1[1010];
int m,n,dx[1010],dy[1010];
bool cmp(node a,node b)
{
	if(a.x==b.x) return a.y<b.y;
	return a.x<b.x;
}
void dfs(int x,int y,int step,int sx,int sy,int st)
{
	if(step==m)
	{
		printf("%d %d\n",sx-p[1].x,sy-p[1].y);
		exit(0);	
	}
	for(int i=st;i<=n;i++)
	{
		if(p1[i].x-x==dx[step]&&p1[i].y-y==dy[step]) 
			dfs(p1[i].x,p1[i].y,step+1,sx,sy,i);
		if(p1[i].x-x>dx[step]) return;
	}
}
int main()
{
	//fre();
	scanf("%d",&m);
	for(int i=1;i<=m;i++) scanf("%d%d",&p[i].x,&p[i].y);
	sort(p+1,p+1+m,cmp);
	for(int i=2;i<=m;i++) 
		dx[i-1]=p[i].x-p[i-1].x,dy[i-1]=p[i].y-p[i-1].y;
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d%d",&p1[i].x,&p1[i].y);
	sort(p1+1,p1+1+n,cmp);
	for(int i=1;i<=n;i++) dfs(p1[i].x,p1[i].y,1,p1[i].x,p1[i].y,i);
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值