• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            uva 10112 - Myacm Triangles

               這是一個幾何題。題意是給出一系列點,點最多才15個,求一個這里面的三個點組合出來的三角形,其面積是最大的,而且沒有任何其它
            的點在這個三角形的內部和邊界上。求三角形的面積,題目上面已經給了公式,也可以用0.5*|a|*|b|*sin(a,b)求,這里的a和b指的是2條
            邊代表的向量。
               現在就剩下一個問題了,怎么判斷一個點在三角形的內部和邊界上。在邊界上,比較好判斷,判斷是否共線,然后再點是在線段的內部。
            具體說明下,判斷一個點在三角形內部的思路。我用的還是線性規劃的思想。如果該點在三角形的內部,那么任取三角形的一條邊,
            該內部點和剩余的三角形的一個頂點必定在三角形的那條的邊的同一側。
            這個方法也可以推廣到N邊的凸多邊形,證明的話很簡單,
            因為線性規劃一直在劃分區域。所以,劃分到最后圍起來的區域就是凸多邊形的內部了。
               至于寫代碼的話,由于是第一次寫這種幾何題,寫得很凌亂。

               代碼如下:
            #include <stdio.h>
            #include <math.h>

            #define MAX (20)
            int nN;
            struct Point
            {
                char szLabel[5];
                int x;
                int y;
            };
            Point points[MAX];

            //三點是否共線
            bool IsOneLine(int nOne, int nTwo, int nThree)
            {
                int nA = points[nTwo].x - points[nOne].x;
                int nB = points[nTwo].y - points[nOne].y;
                int nC = points[nThree].x - points[nOne].x;
                int nD = points[nThree].y - points[nOne].y;
                
                return (nA * nD == nB * nC);
            }

            //點nOne和點nTwo是否在直線(nBeg,nEnd)的同一側(不能在直線上)
            bool IsSameSide(int nBeg, int nEnd, int nOne, int nTwo)
            {
                //求直線的向量
                int nA = points[nBeg].x - points[nEnd].x;
                int nB = points[nBeg].y - points[nEnd].y;
                
                //直線方程為nB(x - points[nBeg].x) - nA(y - points[nBeg].y) = 0
                
            //分別用nOne和nTwo的坐標代入直線方程計算結果,然后將結果相乘
                
            //乘積必須大于0
                int nRes = (nB * (points[nOne].x - points[nBeg].x) - nA * (points[nOne].y - points[nBeg].y))
                * (nB * (points[nTwo].x - points[nBeg].x) - nA * (points[nTwo].y - points[nBeg].y));
                
                if (nRes > 0)
                {
                    //printf("點:%d,點:%d,在直線nBeg:%d, nEnd:%d的同一側\n", nOne, nTwo, nBeg, nEnd);
                }
                return nRes > 0;
            }

            //點是否在三角形(nOne, nTwo, nThree)外部
            bool PointOutTriangle(int nOne, int nTwo, int nThree, int nPoint)
            {
                //前面3個ifelse是判斷點是否在邊上
                if (IsOneLine(nOne, nTwo, nPoint))
                {
                    if ((points[nOne].x - points[nPoint].x) * (points[nTwo].x - points[nPoint].x) <= 0)
                    {
                        return false;
                    }
                }
                else if (IsOneLine(nOne, nThree, nPoint))
                {
                    if ((points[nOne].x - points[nPoint].x) * (points[nThree].x - points[nPoint].x) <= 0)
                    {
                        return false;
                    }
                }
                else if (IsOneLine(nTwo, nThree, nPoint))
                {
                    if ((points[nTwo].x - points[nPoint].x) * (points[nThree].x - points[nPoint].x) <= 0)
                    {
                        return false;
                    }
                }
                
                //下面的IsSameSide如果nPoint在直線的(nOne,nTwo)的外側也會判斷為假
                
            //所以需要先在上面判斷點是否在邊的內側
                return !(IsSameSide(nOne, nTwo, nThree, nPoint)
                && IsSameSide(nOne, nThree, nTwo, nPoint)
                && IsSameSide(nTwo, nThree, nOne, nPoint));
            }

            bool IsValid(int nOne, int nTwo, int nThree)
            {
                if (IsOneLine(nOne, nTwo, nThree))
                {
                    //printf("點:%d,%d,%d共線\n", nOne, nTwo, nThree);
                    return false;
                }
                
                for (int i = 0; i < nN; ++i)
                {
                    if (i == nOne || i == nTwo || i == nThree)
                    {
                        continue;
                    }

                    if (!PointOutTriangle(nOne, nTwo, nThree, i))
                    {
                        //printf("點:%d, 在三角形:%d,%d,%d內部\n", i, nOne, nTwo, nThree);
                        return false;
                    }
                }
                
                return true;
            }

            //計算三角形(nOne, nTwo, nThree)的面積
            double GetArea(int nOne, int nTwo, int nThree)
            {
                return 0.5 * fabs((points[nThree].y - points[nOne].y) * (points[nTwo].x - points[nOne].x)
                - (points[nTwo].y - points[nOne].y) * (points[nThree].x - points[nOne].x));
            }

            int main()
            {
                while (scanf("%d", &nN), nN)
                {
                    for (int i = 0; i < nN; ++i)
                    {
                        scanf("%s%d%d", points[i].szLabel, &points[i].x, &points[i].y);
                    }
                    
                    double fMaxArea = 0.0;
                    int nI = -1, nJ = -1, nK = -1;
                    for (int i = 0; i < nN - 2; ++i)
                    {
                        for (int j = i + 1; j < nN - 1; ++j)
                        {
                            for (int k = j + 1; k < nN; ++k)
                            {
                                if (IsValid(i, j, k))
                                {
                                    //printf("i:%d,j:%d,k:%d valid\n", i, j, k);
                                    double fArea = GetArea(i, j, k);
                                    //printf("Area:%f\n", fArea);
                                    if (fArea > fMaxArea)
                                    {
                                        nI = i;
                                        nJ = j;
                                        nK = k;
                                        fMaxArea = fArea;
                                    }
                                }
                            }
                        }
                    }
                    printf("%s%s%s\n", points[nI].szLabel, points[nJ].szLabel, points[nK].szLabel);
                }
                
                return 0;
            }

            posted on 2012-05-07 14:07 yx 閱讀(1284) 評論(0)  編輯 收藏 引用 所屬分類: 數學題

            <2011年12月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            導航

            統計

            公告

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            me

            好友

            同學

            網友

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            99久久无色码中文字幕人妻| www.久久热.com| 色综合久久久久无码专区| 久久精品视频91| 久久免费99精品国产自在现线| 久久婷婷五月综合色奶水99啪| 久久国产成人午夜aⅴ影院| 国产Av激情久久无码天堂| 久久九九久精品国产免费直播| 2022年国产精品久久久久| 精品一区二区久久| 91久久国产视频| 久久久久国色AV免费看图片| 亚洲国产精品嫩草影院久久| 色综合久久久久综合99| 亚洲国产成人精品久久久国产成人一区二区三区综 | 久久99精品久久久久久噜噜| 一个色综合久久| 亚洲欧美另类日本久久国产真实乱对白 | 国产精品熟女福利久久AV| 99久久国产亚洲高清观看2024| 狠色狠色狠狠色综合久久| 国产一级做a爰片久久毛片| 国产精品天天影视久久综合网| 丁香久久婷婷国产午夜视频| 久久人人爽人人爽人人片AV东京热| 久久久WWW免费人成精品| 久久久久青草线蕉综合超碰| 狠狠色狠狠色综合久久| 亚洲AV无码久久寂寞少妇| www亚洲欲色成人久久精品| 亚洲伊人久久综合中文成人网| 久久精品www人人爽人人| 久久国产视屏| 99久久精品国产一区二区蜜芽| 日韩va亚洲va欧美va久久| AV无码久久久久不卡网站下载| 久久久一本精品99久久精品88| 香蕉久久一区二区不卡无毒影院| 久久精品国产免费观看 | 中文成人无码精品久久久不卡|