poj 1133 POJ 1133

这题要求的就是图形的旋转与缩放,然后再与原图进行匹配,需要注意的一点是图形本身就有可能能够通过旋转得到

ps:我的代码其实是过不了的,因为复杂度达到了n*n*n,而题上要求的n是1000,但是因为poj的数据没有大数据所以过了,囧~~~~

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<algorithm>
#define max_n 10000000
#define inf 0x7ffffff
using namespace std;
const double eps=1e-12;
int flag,ans;
struct P
{
	double x,y;
	double light;
};
P p[max_n],l[max_n],as[max_n];
int n,m,k;
double dis(P a,P b)
{
	double c=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
	return sqrt(c);
}
P get_move(P a,P b,double angle,double s)
{
	P c;
	b.x-=a.x;
	b.y-=a.y;
	c.x=cos(angle)*b.x*s-sin(angle)*b.y*s+a.x;
	c.y=cos(angle)*b.y*s+sin(angle)*b.x*s+a.y;
	return c;
}
double mxn;
bool cp(P a,P b)
{
	if(a.x!=b.x)
	return a.x<b.x;
	return a.y<b.y;
}
bool equ(P a,P b)
{
	if(fabs(a.x-b.x)<eps && fabs(a.y-b.y)<eps)
		return 1;
	return 0;
}P kk[max_n];P cmp[max_n];
void solve()
{
	mxn=-inf;
	int lkk=0;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(i==j)
				continue;
			double angle,s;
			double sum=0;
			cmp[0]=p[i];
			kk[0]=p[i];
			cmp[1]=p[j];
			kk[1]=p[j];
			sum+=p[i].light;
			sum+=p[j].light;
			int a;
			lkk=2;
			for( a=2;a<k;a++)
			{
				angle=atan2(l[a].y-l[0].y,l[a].x-l[0].x)-atan2(l[1].y-l[0].y,l[1].x-l[0].x);
				s=dis(l[a],l[0])/dis(l[1],l[0]);
				cmp[a]=get_move(p[i],p[j],angle,s);
				int fg=0;
				for(int ii=0;ii<n;ii++)
				{
					if(equ(p[ii],cmp[a]))
					{
						sum+=p[ii].light;
						kk[lkk++]=p[ii];
						fg=1;
						break;
					}
				}
				if(!fg)
					break;
			}
			if(a!=k)
				continue;
			flag=1;
			ans++;
			if(sum>mxn)
			{
				mxn=sum;
				for(int llp=0;llp<k;llp++)
				{
					as[llp]=kk[llp];
				}
			}
		}
	}
}
int jisuan()
{
	int bns=0;
	mxn=-inf;
	int lkk=0;
	for(int i=0;i<k;i++)
	{
		for(int j=0;j<k;j++)
		{
			if(i==j)
				continue;
			double angle,s;
			double sum=0;
			cmp[0]=l[i];
			kk[0]=l[i];
			cmp[1]=l[j];
			kk[1]=l[j];
			int a;
			lkk=2;
			for( a=2;a<k;a++)
			{
				angle=atan2(l[a].y-l[0].y,l[a].x-l[0].x)-atan2(l[1].y-l[0].y,l[1].x-l[0].x);
				s=dis(l[a],l[0])/dis(l[1],l[0]);
				cmp[a]=get_move(l[i],l[j],angle,s);
				int fg=0;
				for(int ii=0;ii<k;ii++)
				{
					if(equ(l[ii],cmp[a]))
					{
						kk[lkk++]=l[ii];
						fg=1;
						break;
					}
				}
				if(!fg)
					break;
			}
			if(a!=k)
				continue;
			bns++;
		}
	}
	return bns;
}
char name[1000];
int main()
{
	//freopen("kepin.txt","r",stdin);
	//freopen("outout.txt","w",stdout);
	double kkk=-1;
	int mink;
	int step=1;
	while(~scanf("%d",&n) && n)
	{
		kkk=-1;
		printf("Map #%d\n",step++);
		for(int i=0;i<n;i++)
		{
				scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].light);
				if(kkk<p[i].light)
				{
					kkk=p[i].light;
					mink=i;
				}
		}
		scanf("%d",&m);
		for(int i=0;i<m;i++)
		{
			flag=0;
			ans=0;
			
			scanf("%d%s",&k,name);
			for(int i=0;i<k;i++)
				scanf("%lf%lf",&l[i].x,&l[i].y);
			if(k==1)
			{
				printf("\n");
				printf("%s occurs %d time(s) in the map.\n",name,n);
				printf("Brightest occurrence:");
				printf(" (%.0lf,%.0lf)",p[mink].x,p[mink].y);
				printf("\n");
				continue;
			}
			solve();
			
			int lkj=jisuan();//printf(" %d   %d\n",ans,lkj);
			printf("\n");
			if(lkj!=0)
				ans=ans/lkj;
			printf("%s occurs %d time(s) in the map.\n",name,ans);
			if(flag)
			{
				printf("Brightest occurrence:");
				sort(as,as+k,cp);
				for(int j=0;j<k;j++)
				{
					printf(" (%.0lf,%.0lf)",as[j].x,as[j].y);
				}
				printf("\n");
			}
		}
		printf("-----\n");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值