{HDU}{4082}{Hou Yi's secret}{几何}
11年北京赛区的B题,数据量很小暴力搜索的计算几何,但是有很多小地方需要注意,WA了N次:
- 注意对点判重,否则乎会生成很多一样的三角形
- 三个点在同一条直线上的情况
- 判断相似性的时候不需要判断角度,只需要对边进行比例判定即可
#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <memory>
#include <cmath>
#include <bitset>
#include <queue>
#include <vector>
#include <stack>
using namespace std;
const int MAXN = 20;
#define CLR(x,y) memset(x,y,sizeof(x))
#define MIN(m,v) (m)<(v)?(m):(v)
#define MAX(m,v) (m)>(v)?(m):(v)
#define ABS(x) ((x)>0?(x):-(x))
#define rep(i,x,y) for(i=x;i<y;++i)
typedef struct{
int a,b,c;
}Node;
Node node[100000];
int N,tt,ans;
int a[MAXN][2];
bool _check(int a1,int b1,
int a2,int b2,
int a3,int b3)
{
int x1 = a1-a2;
int y1 = b1-b2;
int x2 = a2-a3;
int y2 = b2-b3;
if ( x1*y2 - x2*y1 == 0)
return false;
return true;
}
int _dist(const int & a1, const int& b1,
const int &a2, const int& b2)
{
return (a1-a2)*(a1-a2)+(b1-b2)*(b1-b2);
}
bool _sim(const int& i, const int& j)
{
if( node[i].a*node[j].b - node[j].a*node[i].b != 0)
return false;
if( node[i].a*node[j].c - node[j].a*node[i].c != 0)
return false;
return true;
}
int work()
{
int i,j,tmp,k;
int x,y;
int v[300][300];
CLR(v,0);
int n = 0;
rep(i,0,N){
scanf("%d%d",&x,&y);
if( v[x+150][y+150] )
continue;
v[x+150][y+150] = true;
a[n][0] = x;
a[n][1] = y;
++n;
}
int cnt = 0;
int e[3];
rep(i,0,n)
rep(j,i+1,n)
rep(k,j+1,n){
if(!_check(a[i][0],a[i][1],
a[j][0],a[j][1],
a[k][0],a[k][1]))
continue;
e[0] = _dist(a[i][0],a[i][1],a[j][0],a[j][1]);
e[1] = _dist(a[i][0],a[i][1],a[k][0],a[k][1]);
e[2] = _dist(a[k][0],a[k][1],a[j][0],a[j][1]);
sort(e,e+3);
node[cnt].a = e[0];
node[cnt].b = e[1];
node[cnt].c = e[2];
++cnt;
}
int mmax;
mmax = 0;
if( cnt > 1 ){
tmp = 1;
rep(i,0,cnt){
tmp = 1;
rep(j,i+1,cnt) {
if(_sim(i,j))
++tmp;
}
if( mmax < tmp )
mmax = tmp;
}
printf("%d\n",mmax);
}else
printf("%d\n",cnt);
return 0;
}
int main()
{
while( scanf("%d",&N) , N ){
work();
}
return 0;
}
浙公网安备 33010602011771号