zoukankan      html  css  js  c++  java
  • HDU

    题意:射箭落在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
    ", ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    消息中间件(一)MQ详解及四大MQ比较
    SIP协议
    PAT (Basic Level) Practice 1008 数组元素循环右移问题
    LeetCode-Algorithms 1. 两数之和
    PAT (Basic Level) Practice 1040 有几个PAT
    PAT (Basic Level) Practice 1023 组个最小数
    PAT (Basic Level) Practice 1021 个位数统计
    PAT (Basic Level) Practice 1007 素数对猜想
    PAT (Basic Level) Practice 1006 换个格式输出整数
    PAT (Basic Level) Practice 1004 成绩排名
  • 原文地址:https://www.cnblogs.com/tyty-Somnuspoppy/p/7241750.html
Copyright © 2011-2022 走看看