HDU - 4082 Hou Yi's secret
题意:射箭落在n个点,任取三点可构成一个三角形,问最大的相似三角形集(一组互相相似的三角形)的个数。
分析:
1、若n个点中有相同的点,要去重,题目中说射箭会形成洞,任选三个洞构成三角形,因此射在同一点只形成一个洞。
2、二进制枚举子集选出三个点,判断能否构成三角形。
3、因为边长可能为小数,因此用边长的平方判断相似。
(1)将比较的两个三角形三边分别排序
(2)tmpx[0] / tmpy[0] = tmpx[1] / tmpy[1] = tmpx[2] / tmpy[2],即若满足tmpx[0] * tmpy[1] == tmpy[0] * tmpx[1] && tmpx[1] * tmpy[2] == tmpx[2] * tmpy[1],则两三角形相似。
#include<cstdio> #include<cstring> #include<cstdlib> #include<cctype> #include<cmath> #include<iostream> #include<sstream> #include<iterator> #include<algorithm> #include<string> #include<vector> #include<set> #include<map> #include<stack> #include<deque> #include<queue> #include<list> #define lowbit(x) (x & (-x)) const double eps = 1e-8; inline int dcmp(double a, double b){ if(fabs(a - b) < eps) return 0; return a > b ? 1 : -1; } typedef long long LL; typedef unsigned long long ULL; const int INT_INF = 0x3f3f3f3f; const int INT_M_INF = 0x7f7f7f7f; const LL LL_INF = 0x3f3f3f3f3f3f3f3f; const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f; const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1}; const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1}; const LL MOD = 1e9 + 7; const double pi = acos(-1.0); const int MAXN = 1000 + 10; const int MAXT = 1000000 + 10; using namespace std; struct Node{ int x, y; }num[20]; struct tri{ LL a, b, c; }num1[MAXN]; int cnt; int cntpoint; vector<int> v; LL tmpx[5]; LL tmpy[5]; map<pair<int, int>, int> mp; bool judge(LL x, LL y){ tmpx[0] = num1[x].a; tmpx[1] = num1[x].b; tmpx[2] = num1[x].c; tmpy[0] = num1[y].a; tmpy[1] = num1[y].b; tmpy[2] = num1[y].c; sort(tmpx, tmpx + 3); sort(tmpy, tmpy + 3); if(tmpx[0] * tmpy[1] == tmpy[0] * tmpx[1] && tmpx[1] * tmpy[2] == tmpx[2] * tmpy[1]) return true; return false; } int main(){ int n; while(scanf("%d", &n) == 1){ if(!n) return 0; mp.clear(); cntpoint = 0; int x, y; for(int i = 0; i < n; ++i){ scanf("%d%d", &x, &y); if(!mp.count(pair<int, int>(x, y))){ mp[pair<int, int>(x, y)] = 1; num[cntpoint].x = x; num[cntpoint++].y = y; } } cnt = 0; for(int i = 0; i < (1 << cntpoint); ++i){ v.clear(); for(int j = 0; j < cntpoint; ++j){ if(i & (1 << j)){ v.push_back(j); } } if(v.size() == 3){ int tmp11 = (num[v[0]].x - num[v[1]].x) * (num[v[0]].x - num[v[1]].x) +(num[v[0]].y - num[v[1]].y) * (num[v[0]].y - num[v[1]].y); int tmp22 = (num[v[1]].x - num[v[2]].x) * (num[v[1]].x - num[v[2]].x) +(num[v[1]].y - num[v[2]].y) * (num[v[1]].y - num[v[2]].y); int tmp33 = (num[v[2]].x - num[v[0]].x) * (num[v[2]].x - num[v[0]].x) +(num[v[2]].y - num[v[0]].y) * (num[v[2]].y - num[v[0]].y); double tmp1 = sqrt(double(tmp11)); double tmp2 = sqrt(double(tmp22)); double tmp3 = sqrt(double(tmp33)); if(dcmp(tmp1 + tmp2, tmp3) > 0 && dcmp(tmp2 + tmp3, tmp1) > 0 && dcmp(tmp1 + tmp3, tmp2) > 0){ num1[cnt].a = (LL)tmp11; num1[cnt].b = (LL)tmp22; num1[cnt].c = (LL)tmp33; ++cnt; } } } int ans = 0; for(int i = 0; i < cnt; ++i){ int sum = 1; for(int j = 0; j < cnt; ++j){ if(i != j){ if(judge(i, j)) ++sum; } } ans = max(ans, sum); } printf("%d\n", ans); } return 0; }