• <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>

            題目要求統(tǒng)計一個平面圖中所有邊數(shù)為k的面的個數(shù)。應(yīng)該是個經(jīng)典問題。說說我的算法吧。
            枚舉每條邊,做以下的基本步驟。

            基本步驟:以這條邊作起始邊,不斷地找下一條“最左轉(zhuǎn)”的邊,并且標(biāo)記每個點的訪問次數(shù),直到某個點第3次被訪問為止。
            經(jīng)過這個步驟之后,得到一個頂點序列。容易知道,當(dāng)且僅當(dāng)這個頂點序列是2-重復(fù)(就是形如12341234這樣),并且是逆時針旋轉(zhuǎn)的,那么就是一個面。
            接下去我們就把所有找到的邊數(shù)為k面進(jìn)行hash去重,就得到答案啦。
            貌似我想的這個算法不夠好,如果有更好的算法,歡迎和我討論。


            /*************************************************************************
            Author: WHU_GCC
            Created Time: 2007-9-7 16:26:27
            File Name: pku1092.cpp
            Description: 
            ***********************************************************************
            */

            #include 
            <iostream>
            #include 
            <cmath>
            using namespace std;

            #define out(x) (cout << #x << ": " << x << endl)
            typedef 
            long long int64;
            const int maxint = 0x7FFFFFFF;
            const int64 maxint64 = 0x7FFFFFFFFFFFFFFFLL;
            template 
            <class T> void show(T a, int n) for (int i = 0; i < n; ++i) cout << a[i] << ' '; cout << endl; }
            template 
            <class T> void show(T a, int r, int l) for (int i = 0; i < r; ++i) show(a[i], l); cout << endl; }

            const int maxn = 210;
            const int prime = 502973;

            typedef 
            struct point_t
            {
                
            int x, y, id;
                
            int cnt_child;
                
            int child[maxn];
            }
            ;

            typedef 
            struct farmland_t
            {
                
            int cnt;
                
            int v[maxn];
            }
            ;

            typedef 
            struct hash_t
            {
                farmland_t farmland;
                hash_t 
            *next;
            }
            ;

            int n, size;
            point_t point[maxn];

            hash_t 
            *hash[prime];

            int operator ==(const farmland_t &a, const farmland_t &b)
            {
                
            if (a.cnt != b.cnt)
                    
            return 0;
                
            for (int i = 0; i < a.cnt; i++)
                    
            if (a.v[i] != b.v[i])
                        
            return 0;
                
            return 1;
            }


            int hash_insert(const farmland_t &farmland)
            {
                unsigned 
            int key = 1;
                
            for (int i = 0; i < farmland.cnt; i++)
                    key 
            *= farmland.v[i];
                key 
            %= prime;

                
            for (hash_t *= hash[key]; t; t = t->next)
                    
            if (t->farmland == farmland)
                        
            return 0;
                hash_t 
            *= new hash_t;
                t
            ->farmland = farmland;
                t
            ->next = hash[key];
                hash[key] 
            = t;
                
            return 1;
            }


            int dot_mul(const point_t &a, const point_t &b)
            {
                
            return a.x * b.x + a.y * b.y;
            }


            int cross_mul(const point_t &a, const point_t &b)
            {
                
            return a.x * b.y - a.y * b.x;
            }


            point_t 
            operator -(const point_t &a, const point_t &b)
            {
                point_t ret;
                ret.x 
            = a.x - b.x;
                ret.y 
            = a.y - b.y;
                
            return ret;
            }


            double len(const point_t &a)
            {
                
            return sqrt(double(a.x * a.x + a.y * a.y));
            }


            double angle_a_to_b(const point_t &a, const point_t &b)
            {
                
            double ret = acos(dot_mul(a, b) / (len(a) * len(b)));
                
            int cross = cross_mul(a, b);
                
            if (cross == 0)
                    
            return 0.0;
                
            else if (cross > 0)
                    
            return -ret;
                
            else
                    
            return ret;
            }


            int find_farmland(int a, int b, farmland_t &farmland)
            {
                
            int stack[maxn * 2];
                
            int top = 2;
                stack[
            0= a;
                stack[
            1= b;
                
            int used[maxn];
                memset(used, 
            0sizeof(used));
                used[a] 
            = used[b] = 1;

                
            while (1)
                
            {
                    
            double min_angle = 1e10;
                    
            int min_i;
                    
            for (int i = 0; i < point[stack[top - 1]].cnt_child; i++)
                    
            {
                        
            int p = point[stack[top - 1]].child[i];
                        
            if (p == stack[top - 2])
                            
            continue;
                        
            double angle = angle_a_to_b(point[stack[top - 1]] - point[stack[top - 2]], point[p] - point[stack[top - 1]]);
                        
            if (angle < min_angle)
                        
            {
                            min_angle 
            = angle;
                            min_i 
            = p;
                        }

                    }

                    
            if (used[min_i] == 2)
                    
            {
                        
            if (min_i != a)
                            
            return 0;
                        
            if (top & 1)
                            
            return 0;
                        
            if (top / 2 != size)
                            
            return 0;
                        
            for (int i = 0; i < top / 2; i++)
                            
            if (stack[i] != stack[i + top / 2])
                                
            return 0;
                        
            int area = 0;
                        
            for (int i = 0; i < top / 2; i++)
                            area 
            += cross_mul(point[stack[i]], point[stack[i + 1]]);
                        
            if (area <= 0)
                            
            return 0;

                        
            {
                            farmland.cnt 
            = top / 2;
                            
            int min = maxint;
                            
            int mini;
                            
            for (int i = 0; i < top / 2; i++)
                                
            if (stack[i] < min)
                                
            {
                                    min 
            = stack[i];
                                    mini 
            = i;
                                }

                            
            for (int i = 0; i < top / 2; i++)
                                farmland.v[i] 
            = stack[mini + i];
                            
            return 1;
                        }

                    }

                    
            else
                    
            {
                        used[min_i]
            ++;
                        stack[top
            ++= min_i;
                    }

                }

            }


            int count_farmland()
            {
                memset(hash, 
            0sizeof(hash));
                
            int cnt = 0;
                
            for (int i = 1; i <= n; i++)
                    
            for (int j = 0; j < point[i].cnt_child; j++)
                    
            {
                        farmland_t farmland;
                        
            int flag = find_farmland(i, point[i].child[j], farmland);
                        
            if (flag)
                            
            if (hash_insert(farmland))
                                cnt
            ++;
                    }

                
            return cnt;
            }


            int main()
            {
                
            int ca;
                
            for (scanf("%d"&ca); ca--;)
                
            {
                    scanf(
            "%d"&n);
                    
            for (int i = 1; i <= n; i++)
                    
            {
                        scanf(
            "%d%d%d%d"&point[i].id, &point[i].x, &point[i].y, &point[i].cnt_child);
                        
            for (int j = 0; j < point[i].cnt_child; j++)
                            scanf(
            "%d"&point[i].child[j]);
                    }

                    scanf(
            "%d"&size);
                    printf(
            "%d\n", count_farmland());
                }

                
            return 0;
            }
            posted on 2007-09-07 19:37 Felicia 閱讀(661) 評論(0)  編輯 收藏 引用 所屬分類: 計算幾何
             
            久久99国产精品成人欧美| 日日躁夜夜躁狠狠久久AV| 99久久精品国产麻豆| 精品久久久久久久无码| 欧美激情精品久久久久| 久久精品无码免费不卡| 无码人妻久久一区二区三区蜜桃| 色婷婷综合久久久久中文字幕| 久久人妻AV中文字幕| 久久久久亚洲AV成人片| 伊人久久大香线焦综合四虎| 午夜精品久久影院蜜桃| 亚洲国产精品无码久久SM | 久久天天躁狠狠躁夜夜2020老熟妇| 色成年激情久久综合| 久久综合亚洲色一区二区三区 | 成人国内精品久久久久一区| 99久久国产综合精品成人影院| 亚洲精品视频久久久| 久久99精品久久久久婷婷| 精品无码久久久久久久动漫| 久久人人爽人人爽人人爽| 99久久精品免费| 久久精品午夜一区二区福利| 久久国产成人精品国产成人亚洲| 色综合久久久久无码专区| 久久久久九九精品影院| 精品久久久久久久| 亚洲中文字幕无码久久综合网 | 99精品国产综合久久久久五月天 | 亚洲国产高清精品线久久| 99久久人妻无码精品系列| 国内精品久久久久影院薰衣草| 久久久久久久综合综合狠狠| 国内精品久久久久影院优| 午夜人妻久久久久久久久| 2021国产精品久久精品| 亚洲伊人久久成综合人影院 | 色欲综合久久中文字幕网| 狠狠色丁香久久婷婷综合图片| 国产伊人久久|