poj 1696 Space Ant

大致题意:

一只蚂蚁,只会向左转,现在给出平面上很多个点,求解一种走法,
能使得蚂蚁能经过的点最多,每个顶点该蚂蚁只能经过一次,且所行走的路线不能发生交叉.

卷包裹法:

形象思维假想一根无限长的绳子,一开始,左端粘在点集的最低点上。若有多个最低点,则去最做的最低点。然后拉动绳子的另一端逆时针绕行,每次紧贴一条边(这就是凸包上的一条边),这样绕行一周,绳子的形状就是凸包,这就是所谓的卷包裹法;该算法的效率比较低是O(n^2)的时间效率;

View Code
#include<iostream>

#include<cstdio>

#include<cstdlib>

#include<algorithm>

#include<cmath>

#include<queue>

#include<set>

#include<map>

#include<cstring>

#include<vector>

using namespace std;

class Point

{

public:

      int x,y;    

}point[54];

int on_segment( Point p, Point q1,Point q2 )//叉积 

{

   return ( q1.x - p.x )*( q2.y - p.y ) - ( q2.x - p.x )*( q1.y - p.y );      

}

double Distance( Point  a, Point b )//距离计算 

{

    return sqrt( double(( a.x - b.x )*( a.x - b.x ) + ( a.y - b.y )*( a.y - b.y )) );

}

bool segment( Point p, Point q1,Point q2 )

{

    int t = on_segment( p , q1 , q2 );

    if( t < 0 )  return true;

    else if( t==0 && Distance( p , q1 ) > Distance( p , q2 ))

         return true;

    return false;

}

int main(  )

{

    int N,n,num;

    while( scanf( "%d",&N )==1 )

    {

      while( N -- )

      {

           bool visit[54]={0};//标记已经进入凸包的点 

           int record[54],count=0;//记录点顺序 

           scanf( "%d",&n );

           int min_y = 0x7fffffff,t=0; 

           for( int i = 1; i <= n ; i++ )

           {

              scanf( "%d %d %d",&num,&point[i].x , &point[i].y );

              if( point[i].y < min_y )//寻找最低点 

              {

                 min_y = point[i].y;

                 t = i;

              }        

           }

           record[++count] = t; visit[t] = true;

           while( count < n )

           {

              int temp,s=record[count];//最新的凸包起点 

              for( int i = 1 ; i <= n ; i ++ )//寻找新的凸包起点 

              {

                  if( !visit[i] )

                  {

                    temp = i;

                    break;    

                  }        

              }        

              for( int i = 1 ; i <= n ; i++ )//寻找最优的凸包起点 

              {

                 if( !visit[i] && i != temp )

                 {

    

                     if( segment( point[s],point[temp],point[i] )  )

                     {

                         temp = i;        

                     }         

                 }    

              }

              visit[temp] = true; 

              record[++count] = temp;

           }

           printf( "%d",count );

           for( int i = 1; i <= count ; i++ )

           {

              printf( " %d",record[i] );        

           }

           puts( "" );

          }

    } 

    //system( "pause" );

    return 0;

}

 下面用Graham—Scan算法:用极坐标排序。

View Code
#include<iostream>

#include<cstdio>

#include<cstdlib>

#include<algorithm>

#include<cmath>

#include<queue>

#include<set>

#include<map>

#include<cstring>

#include<vector>

using namespace std;

class Point

{

public:

      int x,y,num;    

}point[54];

int pos;

double Distance( Point a, Point b )

{

   return sqrt( double(( a.x - b.x )*( a.x - b.x ) + ( a.y - b.y )*( a.y - b.y )) );    

}

int segment( Point p1 ,Point p2 ,Point q )

{

    return     ( p1.x - q.x )*( p2.y - q.y ) - ( p2.x - q.x )*( p1.y - q.y );

} 

bool cmp( Point  a, Point  b )

{

    int t = segment( a , b, point[pos] ); 

    if( t > 0 ) return true;

    else if( t==0 && Distance( a , point[pos] ) < Distance( b , point[pos] )) 

         return true;

    return false;

}

int main(  )

{

    int N,n,num;

    while( scanf( "%d",&N )==1 )

    {

        while( N -- )

        {

           scanf( "%d",&n );

           for( int i = 0 ; i < n ; i ++ )

           {

              scanf( "%d %d %d",&point[i].num , &point[i].x ,&point[i].y );

              if( point[i].y < point[0].y )

                 swap( point[0],point[i] );        

           }

           printf( "%d %d",n ,point[0].num );

           for( int i = 1 ; i < n ; i++ )

           {

               pos = i - 1;

               sort( point + i , point + n ,cmp );//极坐标排序 

               printf( " %d",point[i].num );

           }    

           puts( "" );

        }    

    }

    //system( "pause" );

    return 0;

}

 

 

你可能感兴趣的:(ant)