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

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

            基本步驟:以這條邊作起始邊,不斷地找下一條“最左轉”的邊,并且標記每個點的訪問次數,直到某個點第3次被訪問為止。
            經過這個步驟之后,得到一個頂點序列。容易知道,當且僅當這個頂點序列是2-重復(就是形如12341234這樣),并且是逆時針旋轉的,那么就是一個面。
            接下去我們就把所有找到的邊數為k面進行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 閱讀(654) 評論(0)  編輯 收藏 引用 所屬分類: 計算幾何
             
            国产高清国内精品福利99久久| 久久久精品波多野结衣| 精品久久久久香蕉网| 亚洲欧美精品伊人久久| 久久影院亚洲一区| 97久久综合精品久久久综合| 精品国产综合区久久久久久 | 国内精品综合久久久40p| 久久人人爽人人爽人人片AV不 | 2020久久精品国产免费| 久久久久国产| 国产精品天天影视久久综合网| 内射无码专区久久亚洲| 99国产精品久久| 伊人久久精品无码二区麻豆| 狠狠人妻久久久久久综合蜜桃| 国产亚洲精品久久久久秋霞| 国产福利电影一区二区三区久久老子无码午夜伦不 | 亚洲精品无码久久久久去q| 国产精品VIDEOSSEX久久发布 | 天堂无码久久综合东京热| 久久99精品国产一区二区三区| 久久精品国产99国产精品导航| 狠狠人妻久久久久久综合| 成人久久综合网| 久久99国产综合精品女同| 久久人人爽人人爽人人片AV不 | 日本久久久久久中文字幕| 中文字幕乱码久久午夜| 无码国内精品久久人妻麻豆按摩| AAA级久久久精品无码区| 国产成人精品久久一区二区三区 | 国产精品热久久无码av| 99久久精品国内| 国产精品久久影院| 久久亚洲欧洲国产综合| 国产精品嫩草影院久久| 99麻豆久久久国产精品免费| 日本久久久久久中文字幕| 国产精品国色综合久久| 亚洲色欲久久久综合网东京热|