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; }