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

            Uriel's Corner

            Research Associate @ Harvard University / Research Interests: Computer Vision, Biomedical Image Analysis, Machine Learning
            posts - 0, comments - 50, trackbacks - 0, articles - 594

            POJ 1873 The Fortified Forest---凸包+枚舉

            Posted on 2010-05-05 21:04 Uriel 閱讀(569) 評論(2)  編輯 收藏 引用 所屬分類: POJ計算幾何
                    慚愧,這題從中午寫到晚上,一開始一直卡著調(diào)也調(diào)不了,搞到晚上沒辦法換了個凸包模板,然后歷經(jīng)各種NC錯誤終于AC。。                                                          
                    浙大模板凸包那里應(yīng)該沒什么問題,用過多少次了,應(yīng)該是自己寫掛了吧。。- -             
                    題意是有n棵樹,每棵的坐標,價值和長度已知,要砍掉若干根,用他們圍住其他樹,問損失價值最小的情況下又要長度足夠圍住其他樹,砍掉哪些樹。。                                
                     Discuss稱這題為Final的水題。。于是我也水過去了。。枚舉+構(gòu)造凸包判可行。。代碼如下。。凸包那里可以無視。。- -直接貼模板的。。
            /*
            Problem: 1873        User: Uriel
            Memory: 192K        Time: 454MS
            Language: C++        Result: Accepted
            */

            #include
            <math.h>
            #include
            <stdio.h>
            #include
            <stdlib.h>
            #include
            <algorithm>
            using namespace std;

            struct point
            {
                
            int flag;
                
            double x,y,v,l;
            }
            ;

            point P[
            100],convex[100],p1[100],p2[100],p[100];
            double resl,suml,sumv,minv,ans;
            int n,ansn;

            double Dis(point a,point b)
            {
                
            return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
            }


            double multiply(const point& sp,const point& ep,const point& op) 
            {
                  
            return((sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y));
            }


            bool cmp(point a,point b)
            {
                
            return a.flag < b.flag;
            }


            int partition(point a[],int p,int r) 
            {
                
            int i=p,j=r+1,k;
                
            double ang,dis;
                point R,S;
                k
            =(p+r)/2;
                R
            =a[p];a[p]=a[k];a[k]=R;R=a[p];
                dis
            =Dis(R,a[0]);
                
            while(1
                
            {
                    
            while(1
                    
            {
                        
            ++i;
                        
            if(i>r) 
                        
            {
                            i
            =r;
                            
            break;
                        }

                        ang
            =multiply(R,a[i],a[0]);
                        
            if(ang>0)
                            
            break;
                        
            else if(ang==0
                        
            {
                            
            if(Dis(a[i],a[0])>dis)
                            
            break;
                        }

                    }

                    
            while(1
                    
            {
                         
            --j;
                        
            if(j<p) 
                        
            {
                            j
            =p;
                            
            break;
                        }

                        ang
            =multiply(R,a[j],a[0]);
                        
            if(ang<0)
                            
            break;
                        
            else if(ang==0
                        
            {
                            
            if(Dis(a[j],a[0])<dis)
                                
            break;
                        }

                    }

                    
            if(i>=j)break;
                    S
            =a[i];
                    a[i]
            =a[j];
                    a[j]
            =S;
                }

                a[p]
            =a[j];
                a[j]
            =R;
                
            return j;
            }


            void anglesort(point a[],int p,int r) 
            {
                
            if(p<r) 
                
            {
                    
            int q=partition(a,p,r);
                    anglesort(a,p,q
            -1);
                    anglesort(a,q
            +1,r);
                }

            }


            /*PointSet傳入散點,凸包上的點存在ch,n為點數(shù),len為凸包頂點數(shù)*/
            void Graham_scan(point PointSet[],point ch[],int n,int &len) 
            {
                
            int i,k=0,top=2;
                point tmp;
                
            for(i=1;i<n;i++)
                    
            if ( PointSet[i].x<PointSet[k].x ||
                        (PointSet[i].x
            ==PointSet[k].x) && (PointSet[i].y<PointSet[k].y))
                           k
            =i;
                tmp
            =PointSet[0];
                PointSet[
            0]=PointSet[k];
                PointSet[k]
            =tmp;
                anglesort(PointSet,
            1,n-1);
                
            if(n<3
                
            {
                    len
            =n;
                    
            for(int i=0;i<n;i++) ch[i]=PointSet[i];
                    
            return ;
                }

                ch[
            0]=PointSet[0];
                ch[
            1]=PointSet[1];
                ch[
            2]=PointSet[2];
                
            for (i=3;i<n;i++
                
            {
                    
            while (multiply(PointSet[i],ch[top],ch[top-1])>=0) top--;
                     ch[
            ++top]=PointSet[i];
                }

                len
            =top+1;
            }


            int main()
            {
                
            int cse,g=1,i,j,k1,M,k2;
                
            while(scanf("%d",&n),n)
                
            {
                    
            for(i=0;i<n;i++)
                    
            {
                        scanf(
            "%lf %lf %lf %lf",&P[i].x,&P[i].y,&P[i].v,&P[i].l);
                        P[i].flag
            =i+1;
                    }

                    minv
            =1e20;
                    
            for(i=0;i<(1<<n);i++)
                    
            {
                        k1
            =0;k2=0;
                        sumv
            =0;suml=0;
                        
            for(j=0;j<n;j++)
                        
            {
                            
            if(!(i & (1<<j)))
                            
            {
                                p1[k1].x
            =P[j].x;
                                p1[k1].y
            =P[j].y;
                                k1
            ++;
                            }

                            
            else
                            
            {
                                p2[k2].flag
            =P[j].flag;
                                sumv
            +=P[j].v;
                                suml
            +=P[j].l;
                                k2
            ++;
                            }

                        }

                        Graham_scan(p1,convex,k1,M);
                        resl
            =0;
                        
            for(int j=0;j<M-1;j++)
                        
            {
                            resl
            +=Dis(convex[j],convex[j+1]);
                        }

                        resl
            +=Dis(convex[0],convex[M-1]);
                        
            if(resl<=suml && sumv<minv)
                        
            {
                            ans
            =suml-resl;
                            minv
            =sumv;
                            ansn
            =k2;
                            
            for(j=0;j<k2;j++)p[j].flag=p2[j].flag;
                        }

                    }

                    printf(
            "Forest %d\n",g++);
                    printf(
            "Cut these trees:");
                    
            for(i=0;i<ansn;i++)if(p[i].flag!=p[i-1].flag)printf(" %d",p[i].flag);
                    printf(
            "\n");
                    printf(
            "Extra wood: %.2lf\n\n",ans);
                }

            //    system("PAUSE");
                return 0;
            }

            Feedback

            # re: POJ 1873 The Fortified Forest---凸包+枚舉  回復(fù)  更多評論   

            2012-03-20 20:24 by debuger
            5
            1 1 2 2
            2 2 3 3
            3 3 4 4
            4 4 5 5
            5 5 6 6
            崩潰數(shù)據(jù)

            # re: POJ 1873 The Fortified Forest---凸包+枚舉  回復(fù)  更多評論   

            2012-03-20 21:02 by Uriel
            @debuger
            謝謝提醒,原來沒有考慮共線的情況,有共線時凸包那里會有bug
            似乎改成這樣就可以
            while (multiply(PointSet[i], ch[top], ch[top - 1]) >= 0 && top >= 1) top--;
            還有問題的話歡迎指教~
            国内精品久久久久国产盗摄| 性做久久久久久久久久久| 久久久国产乱子伦精品作者| 国内精品久久久久影院日本| 国产精品热久久毛片| 无码国内精品久久综合88| 久久99国产亚洲高清观看首页| 色综合久久久久综合99| 国产精品对白刺激久久久| 青青热久久国产久精品| 久久精品这里热有精品| 少妇熟女久久综合网色欲| 999久久久国产精品| 午夜天堂精品久久久久| 久久亚洲视频| 伊人久久免费视频| 久久精品国产精品亚洲毛片 | 国产成人久久激情91| 香蕉久久AⅤ一区二区三区| 日本精品久久久久中文字幕| 99久久99久久精品国产片果冻| 久久精品国产国产精品四凭| 国产V综合V亚洲欧美久久| 99久久这里只精品国产免费| 欧美日韩精品久久久久| 国产69精品久久久久99尤物| 91精品国产高清久久久久久io| 97久久国产综合精品女不卡| 午夜精品久久久久久| 久久久久久国产精品美女| 国产精自产拍久久久久久蜜| 婷婷综合久久狠狠色99h| 99久久777色| 国产精品久久国产精麻豆99网站| 日韩久久久久久中文人妻| 一本色综合网久久| 久久精品亚洲AV久久久无码| 亚洲日韩中文无码久久| 亚洲AV无码久久精品成人| 日韩精品久久久久久久电影蜜臀 | 久久精品一区二区三区AV|