• POJ 1696


    这题是明显的TU包变形。

    使用卷包裹法可解,而且是必定可以经过所有点的。直观可知,当经过某点后,相当于把之前的点抹去,求剩下点的TU包,递归下去,也就能把点全部经过了。

    于是,只需把经过的点标记一下就可以了。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <cmath>
    
    using namespace std;
    const double inf=10000000;
    const double eps=0.00000001;
    struct point {
    	double x,y;
    	int num;
    }p[60];
    
    bool vis[60];
    queue<int>que;
    struct vect{
    	double x,y;
    };
    
    double dist(point a,point b){
    	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    
    double cross(point a,point b,point c,point d){
    	return (a.x-b.x)*(c.y-d.y)-(a.y-b.y)*(c.x-d.x);
    }
    
    int n;
    int main(){
    	int t;
    	scanf("%d",&t); double a,b;
    	while(t--){
    		scanf("%d",&n);
    		point start; start.x=inf; start.y=inf; int dep;
    		for(int i=0;i<n;i++){
    			scanf("%d%lf%lf",&p[i].num,&p[i].x,&p[i].y);
    			if(p[i].y<start.y){
    				start.x=p[i].x; start.y=p[i].y; start.num=p[i].num;
    				dep=i;
    			}
    			else if(p[i].y==start.y){
    				if(p[i].x<start.x){
    					start.x=p[i].x; start.num=p[i].num;
    					dep=i;
    				}
    			}
    		}
    	//	cout<<start.x<<' '<<start.y<<endl;
    		point last; last.x=0; last.y=start.y;
    		que.push(start.num);
    		memset(vis,false,sizeof(vis));
    		vis[dep]=true; point tmp;
    		while(true){
    			bool flag=false;
    			for(int i=0;i<n;i++){
    				if(vis[i]==false){
    					if(cross(start,last,p[i],start)>=0){
    						tmp=p[i];
    						dep=i;
    						flag=true;
    						break;
    					}
    				}
    			}
    		//	cout<<dep<<"YES"<<endl;
    			if(!flag) break;
    			for(int i=0;i<n;i++){
    				if(vis[i]==false){
    					if(cross(start,last,p[i],start)<0) continue;
    					double res=cross(tmp,start,p[i],start);
    					if(res<0){
    						tmp=p[i];
    						dep=i;
    					}
    					else if(res==0){
    						if(dist(p[i],start)+eps<dist(tmp,start)){
    							tmp=p[i];
    							dep=i;
    						}
    					}
    				}
    			}
    			que.push(tmp.num);
    			//cout<<dep<<endl;
    			vis[dep]=true;
    			last=start;
    			start=tmp;
    		}
    		printf("%d",n);
    		for(int i=0;i<n;i++){
    			printf(" %d",que.front());
    			que.pop();
    		}
    		printf("
    ");
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    深入.NET平台和C#编程笔记第三章
    深入.NET平台和C#编程第1章
    深入.NET平台和C#编程笔记第二章
    内部类
    java对象序列化的概念
    HTML第六章
    CIC 抽取滤波器 Verilog Code
    Cordic 算法的原理介绍
    以太网PHY 芯片之 MII/MDIO接口详解
    常见的FPGA内串行数据采样的方式
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/3879458.html
Copyright © 2020-2023  润新知