2011 ACM/ICPC 北京现场赛 B HouYi's secret

周日起床后看见QQ群消息说 bupt上有半同步北京现场赛试题,就进入看了下题,一共读了两个题 A和B(因为这两个题目当时就都提交的很多)

A题不会做,有限制的生成树的这类知识好像还没有接触过。。。

B题 感觉数据非常小,觉得暴力枚举也能过 就试着写了下 提交几次后竟然过了 嘿嘿

B题题意大致是 给你多个点,让任意三个点可以组合三角形的构成三角形,并把这些三角形分成N个集合,每个集合内的三角形 两两相似,问最大的一个集合有多少个三角形。我的写法 是以此枚举三个点看能否够成三角形,如果能构成三角形 就先把三角存起来,继续枚举。。。  最后拿每一个三角形和所有的三角形比较看是否相似,记录相似个数,输出最大一个数就可以了(一句话概括就是输入n个点,求最多的相似三角形个数)

主要有三点需要注意一是输入点时记得去重   二是判断共线的  不能用斜率相等,因为有斜率不存在的情况,     三是精度,double不能用==判断是否相等

下面是我的代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;
double a[20],b[20];
double v[900][3];
int zero(double a,double b)
{
	if(a-b<0.000001&&a-b>-0.000001) return 1;
	if(b-a<0.000001&&b-a>-0.000001) return 1;
	return 0;
}
int main()
{
	int n,m,i,j,k,N;
	while(scanf("%d",&n)&&n)
	{
		N=0;
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		memset(v,0,sizeof(v));
		for(i=0;i<n;i++)
		{
			scanf("%lf%lf",&a[i],&b[i]);
			for(j=0;j<N;j++)
				if(a[i]==a[j]&&b[i]==b[j]) break;
			if(j==N) { a[N]=a[i]; b[N]=b[i]; N++;}
		}
		m=0;
		for(i=0;i<N;i++)
			for(j=0;j<i;j++)
				for(k=0;k<j;k++)
					if(!zero((a[k]-a[j])*(b[j]-b[i]),(a[j]-a[i])*(b[k]-b[j])))
					{
						v[m][0] = sqrt( (a[i]-a[j])*(a[i]-a[j])+(b[i]-b[j])*(b[i]-b[j]) );
						v[m][1] = sqrt( (a[j]-a[k])*(a[j]-a[k])+(b[j]-b[k])*(b[j]-b[k]) );
						v[m][2] = sqrt( (a[k]-a[i])*(a[k]-a[i])+(b[k]-b[i])*(b[k]-b[i]) );
						m++;
					}
		int num,max=0;
		for(i=0;i<m;i++)
			for(num=0,j=0;j<m;j++)

				     if( zero(v[i][0]/v[j][0],v[i][1]/v[j][1]) && zero(v[i][2]/v[j][2],v[i][1]/v[j][1]) )  num++;
				else if( zero(v[i][0]/v[j][0],v[i][1]/v[j][2]) && zero(v[i][2]/v[j][1],v[i][1]/v[j][2]) )  num++; 
				else if( zero(v[i][0]/v[j][1],v[i][1]/v[j][0]) && zero(v[i][2]/v[j][2],v[i][1]/v[j][0]) )  num++; 
				else if( zero(v[i][0]/v[j][1],v[i][1]/v[j][2]) && zero(v[i][2]/v[j][0],v[i][1]/v[j][2]) )  num++; 
				else if( zero(v[i][0]/v[j][2],v[i][1]/v[j][1]) && zero(v[i][2]/v[j][0],v[i][1]/v[j][1]) )  num++;
				else if( zero(v[i][0]/v[j][2],v[i][1]/v[j][0]) && zero(v[i][2]/v[j][1],v[i][1]/v[j][0]) )  num++; 
			if(num>max) max=num;
		printf("%d\n",max);
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值