搜索-登山

 
题目描述:
有两个人在山脉的两头,处在同一水平位置。他们要登上山顶,并且保证在任何时刻都处在同一水平位置上。要求制定行走路线,使步数尽量减少。一步是指他们沿着向上或向下走的一段路。每转一次方向(由向上变为向下或者由向下变为向上),步数加一步。
 
输入一个正整数n,接着是n+1个坐标,每行两个整数,分别为x,y坐标。每个坐标代表一个山峰或山谷。用(Xi,Yi)表示第i个坐标。数据满足X1<X2..<Xn+1,Y1=Yn+1<=min(Y2,Y3,..Yn)。存在一个山峰(Xj,Yj),满足Yj>max(Y1,..Yj-1,Yj+1,..Yn+1)。
 
解题方案
该题目的关键点要保证每时每刻两人都要在同一水平线上,因此在步数最少的路线中转折点均出现在两个人中至少有一个人处在山峰或山谷位置。可以列举以下情况:
(1)左边的人在山峰或者山谷,右边的人在山腰(山谷和山峰之间)
(2)右边的人在山峰或者山谷,左边的人在山腰(山谷和山峰之间)
(3)两个人同时处在山峰或者山谷
扩展一个人处在山峰或者山谷的情况可以分为三种情况处理:
(1)处在山峰的人选择向左边或者右边走
(2)处在山谷的人选择向左边或者右边走
(3)处在山腰的人的行走方向需要根据另外一个人是处于山峰还是山谷确定.。如果处在山峰,则方向向下,否则向上。
(3)如果两个人同时处在山峰或山谷,则每个人都有两种选择,因此总共有四种选择。两个人同时处于山峰或山谷的情况可以假设其中一个人同时处于左山腰以及右山腰,另一个人处于山峰或山谷,可以转化为情况(1),(2)来解决。
 
算法采用广度优先搜索算法,搜索时候需要注意以下几点:
(1)节点的判重: 由于对两个人同时处于山峰或者山谷的情况时候两个人都有两种选择,因此存在着扩展出的节点返回以前出现过的位置,因此需要去掉重复节点。
(2)在对节点进行扩展后,无须计算扩展后两个人的具体坐标位置。由于可以保证扩展后的位置中至少有一个人处于山峰或山谷,因此只需要记录下两个人所处的山段(即扩展后的节点中两个人分别位于哪个山峰与山谷之间,对于处于山峰或山谷的节点,山峰和山谷的位置重合)。
(3)找到最少步数的路线后进行回溯求出路线上各个转折点的坐标。在回溯时如果出现处在山峰和山谷之间的位置时,可以根据另一个人所处的山峰或山谷的纵坐标(该位置的纵坐标等于另一个人所处山峰或山谷的纵坐标)求出这个位置的横坐标。
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAXN 30
#define MAXSIZE 4*MAXN*MAXN
#define L_RANGE -0.01
#define R_RANGE 0.01
#define EQUAL(x,y) ((x)-(y)<R_RANGE&&(x)-(y)>L_RANGE)
#define MORETHAN(x,y) ((x)-(y)>=R_RANGE)
#define LESSTHAN(x,y) ((x)-(y)<=L_RANGE)
//enum DIRECTION {UP,DOWN};
typedef struct
{
 int x;
 int y;
 bool peak; //判断该坐标是山峰还是山谷
}coordinateInfo;
typedef struct
{
 //coordinateInfo p;
 int l;
 int r;
}stepInfo;
struct Node
{
 stepInfo p1;//左边人
 stepInfo p2;//右边人
 struct Node *pre; //父节点
 int cnt;
};
typedef struct Node NodeInfo;
void bfs(int,int);
inline bool hasReachedPeak(stepInfo & ,stepInfo &);
inline bool sameCoordinate(coordinateInfo &,coordinateInfo &);
inline bool duplicateNode(NodeInfo &,NodeInfo &);
static void f01(int ,bool ,stepInfo &,stepInfo &);
static void f21(int ,bool ,stepInfo &,stepInfo &);
static void backtrack(NodeInfo *);
static int summit;
static coordinateInfo coordinates[MAXN+1];
static NodeInfo Q[MAXSIZE];
static int open;
static int close;
static NodeInfo *last;
int main(int argc,char **argv)
{
 int n;
 scanf("%d",&n);
 bool peak = false;
 summit = 0;
 for(int i=0;i<n+1;i++)
 {
  scanf("%d %d",&coordinates[i].x,&coordinates[i].y);
  coordinates[i].peak = peak;
  if(coordinates[i].y>coordinates[summit].y)
  {
   summit = i;
  }
  if(peak==true)
   peak = false;
  else
   peak = true;
 }
 int leftBound = 0;
 int rightBound = n;
 bfs(leftBound,rightBound);
 return 0;
}
void bfs(int leftBound,int rightBound)
{
 open=-1,close=-1;
 bool reachPeak = false;
 int left;
 bool ascending;
 open++;
 Q[open].p1.l = Q[open].p1.r = leftBound;
 Q[open].p2.l = Q[open].p2.r = rightBound;
 Q[open].pre = NULL;
 Q[open].cnt = 1;
 if(hasReachedPeak(Q[open].p1,Q[open].p2))
 {
  printf("%d/n",Q[open].cnt);
  printf("%2f %2f %2f %2f/n",coordinates[Q[open].p1.l],coordinates[Q[open].p1.r],coordinates[Q[open].p2.l],coordinates[Q[open].p2.r]);
  return;
 }
 while(close<open&&!reachPeak)
 {
  close++;
  stepInfo *c1,*c2;
  stepInfo temp1,temp2;
  c1 = &Q[close].p1; //左边人
  c2 = &Q[close].p2; //右边人
  //printf("Q[%d]:%d %d %d %d/n",close,c1->l,c1->r,c2->l,c2->r);
  bool leftPersonInValley = c1->l==c1->r&&!coordinates[c1->l].peak;
  bool leftPersonInPeak = c1->l==c1->r&&coordinates[c1->l].peak;
  bool leftPersonOnHillSide = !leftPersonInValley&&!leftPersonInPeak;
  bool rightPersonInValley = c2->l==c2->r&&!coordinates[c2->l].peak;
  bool rightPersonInPeak = c2->l==c2->r&&coordinates[c2->l].peak;
  bool rightPersonOnHillSide = !rightPersonInValley&&!rightPersonInPeak;
//  printf("leftPersonInValley=%d,leftPersonInPeak=%d,leftPersonOnHillSide=%d,rightPersonInValley=%d,rightPersonInPeak=%d,rightPersonOnHillSide=%d",
  // leftPersonInValley,leftPersonInPeak,leftPersonOnHillSide,rightPersonInValley,rightPersonInPeak,rightPersonOnHillSide);
  
  if(leftPersonInValley&&rightPersonOnHillSide)
  {
   //左边人在山谷,右边人在山腰
   //左边人向右
   left = 0;
   ascending = !coordinates[c2->l].peak&&coordinates[c2->r].peak;
   memcpy(&temp1,c1,sizeof(stepInfo));
   memcpy(&temp2,c2,sizeof(stepInfo));
   temp1.r = temp1.l+1;
   if(temp1.r<=rightBound)
   {
    f01(left,ascending,temp1,temp2);
    open++;
    memcpy(&Q[open].p1,&temp1,sizeof(stepInfo));
    memcpy(&Q[open].p2,&temp2,sizeof(stepInfo));
    Q[open].pre = &Q[close];
    Q[open].cnt = Q[close].cnt+1;
    if(hasReachedPeak(Q[open].p1,Q[open].p2))
    {
     reachPeak = true;
     last = &Q[open];
     continue;
    }
    bool duplicate = false;
    for(int i=0;i<open&&!duplicate;i++)
     duplicate = duplicateNode(Q[i],Q[open]);
    if(duplicate)
     open--;
   }
   //左边人向左
   left = 1;
   memcpy(&temp1,c1,sizeof(stepInfo));
   memcpy(&temp2,c2,sizeof(stepInfo));
 
   temp1.l = temp1.r-1;
   if(temp1.l>=leftBound)
   {
    f01(left,ascending,temp1,temp2);
    open++;
    memcpy(&Q[open].p1,&temp1,sizeof(stepInfo));
    memcpy(&Q[open].p2,&temp2,sizeof(stepInfo));
    Q[open].pre = &Q[close];
    Q[open].cnt = Q[close].cnt+1;
    if(hasReachedPeak(Q[open].p1,Q[open].p2))
    {
     reachPeak = true;
     last = &Q[open];
     continue;
    }
    bool duplicate = false;
    for(int i=0;i<open&&!duplicate;i++)
     duplicate = duplicateNode(Q[i],Q[open]);
    if(duplicate)
     open--;
   }
   
  }
  else if(leftPersonInValley&&rightPersonInValley)
  {
   //左边人在山谷,右边人在山谷
   
   //左边人向右,右边人向右
   left = 0;
   memcpy(&temp1,c1,sizeof(stepInfo));
   memcpy(&temp2,c2,sizeof(stepInfo));
   temp1.r = temp1.l+1;
   temp2.r = temp2.l+1;
   
   if(temp1.r<=rightBound&&temp2.r<=rightBound)
   { 
    ascending = !coordinates[temp2.l].peak&&coordinates[temp2.r].peak;
    f01(left,ascending,temp1,temp2);
    open++;
    memcpy(&Q[open].p1,&temp1,sizeof(stepInfo));
    memcpy(&Q[open].p2,&temp2,sizeof(stepInfo));
    Q[open].pre = &Q[close];
    Q[open].cnt = Q[close].cnt+1;
    if(hasReachedPeak(Q[open].p1,Q[open].p2))
    {
     reachPeak = true;
     last = &Q[open];
     continue;
    }
    bool duplicate = false;
    for(int i=0;i<open&&!duplicate;i++)
     duplicate = duplicateNode(Q[i],Q[open]);
    if(duplicate)
     open--;
   }
   //左边人向左,右边人向右
   left = 1;
   memcpy(&temp1,c1,sizeof(stepInfo));
   memcpy(&temp2,c2,sizeof(stepInfo));
   temp1.l = temp1.r-1;
   temp2.r = temp2.l+1;
   
   if(temp1.l>=leftBound&&temp2.r<=rightBound)
   {
    ascending = !coordinates[temp2.l].peak&&coordinates[temp2.r].peak;
    f01(left,ascending,temp1,temp2);
    open++;
    memcpy(&Q[open].p1,&temp1,sizeof(stepInfo));
    memcpy(&Q[open].p2,&temp2,sizeof(stepInfo));
    Q[open].pre = &Q[close];
    Q[open].cnt = Q[close].cnt+1;
    if(hasReachedPeak(Q[open].p1,Q[open].p2))
    {
     reachPeak = true;
     last = &Q[open];
     continue;
    }
    bool duplicate = false;
    for(int i=0;i<open&&!duplicate;i++)
     duplicate = duplicateNode(Q[i],Q[open]);
    if(duplicate)
     open--;
   }
   //左边人向右,右边人向左
   left = 0;
   memcpy(&temp1,c1,sizeof(stepInfo));
   memcpy(&temp2,c2,sizeof(stepInfo));
   temp1.r=temp1.l+1;
   temp2.l=temp2.r-1;
   if(temp1.r<=rightBound&&temp2.l>=leftBound)
   {
    ascending = !coordinates[temp2.l].peak&&coordinates[temp2.r].peak;
    f01(left,ascending,temp1,temp2);
    open++;
    memcpy(&Q[open].p1,&temp1,sizeof(stepInfo));
    memcpy(&Q[open].p2,&temp2,sizeof(stepInfo));
    Q[open].pre = &Q[close];
    Q[open].cnt = Q[close].cnt+1;
    if(hasReachedPeak(Q[open].p1,Q[open].p2))
    {
     reachPeak = true;
     last = &Q[open];
     continue;
    }
    bool duplicate = false;
    for(int i=0;i<open&&!duplicate;i++)
     duplicate = duplicateNode(Q[i],Q[open]);
    if(duplicate)
     open--;
   }
   //左边人向左,右边人向左
   left = 1;
   memcpy(&temp1,c1,sizeof(stepInfo));
   memcpy(&temp2,c2,sizeof(stepInfo));
   temp1.l=temp1.r-1;
   temp2.l=temp2.r-1;
   if(temp1.l>=leftBound&&temp2.l>=leftBound)
   {
    ascending = !coordinates[temp2.l].peak&&coordinates[temp2.r].peak;
    f01(left,ascending,temp1,temp2);
    open++;
    memcpy(&Q[open].p1,&temp1,sizeof(stepInfo));
    memcpy(&Q[open].p2,&temp2,sizeof(stepInfo));
    Q[open].pre = &Q[close];
    Q[open].cnt = Q[close].cnt+1;
    if(hasReachedPeak(Q[open].p1,Q[open].p2))
    {
     reachPeak = true;
     last = &Q[open];
     continue;
    }
    bool duplicate = false;
    for(int i=0;i<open&&!duplicate;i++)
     duplicate = duplicateNode(Q[i],Q[open]);
    if(duplicate)
     open--;
   }
  }
  else if(leftPersonInPeak&&rightPersonOnHillSide)
  {
   //左边人在山峰,右边人在山腰
   //左边人向右
   left = 0;
   ascending = !coordinates[c2->l].peak&&coordinates[c2->r].peak;
   memcpy(&temp1,c1,sizeof(stepInfo));
   memcpy(&temp2,c2,sizeof(stepInfo));
   temp1.r = temp1.l+1;
   if(temp1.r<=rightBound)
   {
    f21(left,ascending,temp1,temp2);
    open++;
    memcpy(&Q[open].p1,&temp1,sizeof(stepInfo));
    memcpy(&Q[open].p2,&temp2,sizeof(stepInfo));
    Q[open].pre = &Q[close];
    Q[open].cnt = Q[close].cnt+1;
    if(hasReachedPeak(Q[open].p1,Q[open].p2))
    {
     reachPeak = true;
     last = &Q[open];
     continue;
    }
    bool duplicate = false;
    for(int i=0;i<open&&!duplicate;i++)
     duplicate = duplicateNode(Q[i],Q[open]);
    if(duplicate)
     open--;
   }
   //左边人向左
   left = 1;
   memcpy(&temp1,c1,sizeof(stepInfo));
   memcpy(&temp2,c2,sizeof(stepInfo));
 
   temp1.l = temp1.r-1;
   if(temp1.l>=leftBound)
   {
    f21(left,ascending,temp1,temp2);
    open++;
    memcpy(&Q[open].p1,&temp1,sizeof(stepInfo));
    memcpy(&Q[open].p2,&temp2,sizeof(stepInfo));
    Q[open].pre = &Q[close];
    Q[open].cnt = Q[close].cnt+1;
    if(hasReachedPeak(Q[open].p1,Q[open].p2))
    {
     reachPeak = true;
     last = &Q[open];
     continue;
    }
    bool duplicate = false;
    for(int i=0;i<open&&!duplicate;i++)
     duplicate = duplicateNode(Q[i],Q[open]);
    if(duplicate)
     open--;
   }
  }else if(leftPersonOnHillSide&&rightPersonInPeak)
  {
   //左边人在山腰,右边人在山峰
   
   //右边人向右
   left = 0;
   ascending = !coordinates[c1->l].peak&&coordinates[c1->r].peak;
   memcpy(&temp1,c2,sizeof(stepInfo));
   memcpy(&temp2,c1,sizeof(stepInfo));
   temp1.r = temp1.l+1;
   if(temp1.r<=rightBound)
   {
    f21(left,ascending,temp1,temp2);
    open++;
    memcpy(&Q[open].p1,&temp2,sizeof(stepInfo));
    memcpy(&Q[open].p2,&temp1,sizeof(stepInfo));
    Q[open].pre = &Q[close];
    Q[open].cnt = Q[close].cnt+1;
    if(hasReachedPeak(Q[open].p1,Q[open].p2))
    {
     reachPeak = true;
     last = &Q[open];
     continue;
    }
    bool duplicate = false;
    for(int i=0;i<open&&!duplicate;i++)
     duplicate = duplicateNode(Q[i],Q[open]);
    if(duplicate)
     open--;
   }
   //右边人向左
   left = 1;
   memcpy(&temp1,c2,sizeof(stepInfo));
   memcpy(&temp2,c1,sizeof(stepInfo));
 
   temp1.l = temp1.r-1;
   if(temp1.l>=leftBound)
   {
    f21(left,ascending,temp1,temp2);
    open++;
    memcpy(&Q[open].p1,&temp2,sizeof(stepInfo));
    memcpy(&Q[open].p2,&temp1,sizeof(stepInfo));
    Q[open].pre = &Q[close];
    Q[open].cnt = Q[close].cnt+1;
    if(hasReachedPeak(Q[open].p1,Q[open].p2))
    {
     reachPeak = true;
     last = &Q[open];
     continue;
    }
    bool duplicate = false;
    for(int i=0;i<open&&!duplicate;i++)
     duplicate = duplicateNode(Q[i],Q[open]);
    if(duplicate)
     open--;
   }
  }else if(leftPersonOnHillSide&&rightPersonInValley)
  {
   //左边人在山腰,右边人在山谷
   
   //右边人向右
   left = 0;
   ascending = !coordinates[c1->l].peak&&coordinates[c1->r].peak;
   memcpy(&temp1,c2,sizeof(stepInfo));
   memcpy(&temp2,c1,sizeof(stepInfo));
   temp1.r = temp1.l+1;
   if(temp1.r<=rightBound)
   {
    f01(left,ascending,temp1,temp2);
    open++;
    memcpy(&Q[open].p1,&temp2,sizeof(stepInfo));
    memcpy(&Q[open].p2,&temp1,sizeof(stepInfo));
    Q[open].pre = &Q[close];
    Q[open].cnt = Q[close].cnt+1;
    if(hasReachedPeak(Q[open].p1,Q[open].p2))
    {
     reachPeak = true;
     last = &Q[open];
     continue;
    }
    bool duplicate = false;
    for(int i=0;i<open&&!duplicate;i++)
     duplicate = duplicateNode(Q[i],Q[open]);
    if(duplicate)
     open--;
   }
   //右边人向左
   left = 1;
   memcpy(&temp1,c2,sizeof(stepInfo));
   memcpy(&temp2,c1,sizeof(stepInfo));
 
   temp1.l = temp1.r-1;
   if(temp1.l>=leftBound)
   {
    f01(left,ascending,temp1,temp2);
    open++;
    memcpy(&Q[open].p1,&temp2,sizeof(stepInfo));
    memcpy(&Q[open].p2,&temp1,sizeof(stepInfo));
    Q[open].pre = &Q[close];
    Q[open].cnt = Q[close].cnt+1;
    if(hasReachedPeak(Q[open].p1,Q[open].p2))
    {
     reachPeak = true;
     last = &Q[open];
     continue;
    }
    bool duplicate = false;
    for(int i=0;i<open&&!duplicate;i++)
     duplicate = duplicateNode(Q[i],Q[open]);
    if(duplicate)
     open--;
   }
  }
  else if(leftPersonInPeak&&rightPersonInPeak)
  {
   //左边人在山峰,右边人在山峰
   //左边人向右,右边人向右
   left = 0;
   ascending = false;
   memcpy(&temp1,c1,sizeof(stepInfo));
   memcpy(&temp2,c2,sizeof(stepInfo));
   temp1.r = temp1.l+1;
   temp2.r = temp2.l+1;
   if(temp1.r<=rightBound&&temp2.r<=rightBound)
   { 
    ascending = !coordinates[temp2.l].peak&&coordinates[temp2.r].peak;
    f21(left,ascending,temp1,temp2);
    open++;
    memcpy(&Q[open].p1,&temp1,sizeof(stepInfo));
    memcpy(&Q[open].p2,&temp2,sizeof(stepInfo));
    Q[open].pre = &Q[close];
    Q[open].cnt = Q[close].cnt+1;
    if(hasReachedPeak(Q[open].p1,Q[open].p2))
    {
     reachPeak = true;
     last = &Q[open];
     continue;
    }
    bool duplicate = false;
    for(int i=0;i<open&&!duplicate;i++)
     duplicate = duplicateNode(Q[i],Q[open]);
    if(duplicate)
     open--;
   }
   //左边人向左,右边人向右
   left = 1;
   memcpy(&temp1,c1,sizeof(stepInfo));
   memcpy(&temp2,c2,sizeof(stepInfo));
   temp1.l = temp1.r-1;
   temp2.r = temp2.l+1;
   if(temp1.l>=leftBound&&temp2.r<=rightBound)
   {
    ascending = !coordinates[temp2.l].peak&&coordinates[temp2.r].peak;
    f21(left,ascending,temp1,temp2);
    open++;
    memcpy(&Q[open].p1,&temp1,sizeof(stepInfo));
    memcpy(&Q[open].p2,&temp2,sizeof(stepInfo));
    Q[open].pre = &Q[close];
    Q[open].cnt = Q[close].cnt+1;
    if(hasReachedPeak(Q[open].p1,Q[open].p2))
    {
     reachPeak = true;
     last = &Q[open];
     continue;
    }
    bool duplicate = false;
    for(int i=0;i<open&&!duplicate;i++)
     duplicate = duplicateNode(Q[i],Q[open]);
    if(duplicate)
     open--;
   }
   //左边人向右,右边人向左
   left = 0;
   memcpy(&temp1,c1,sizeof(stepInfo));
   memcpy(&temp2,c2,sizeof(stepInfo));
   temp1.r=temp1.l+1;
   temp2.l=temp2.r-1;
   if(temp1.r<=rightBound&&temp2.l>=leftBound)
   {
    ascending = !coordinates[temp2.l].peak&&coordinates[temp2.r].peak;
    f21(left,ascending,temp1,temp2);
    open++;
    memcpy(&Q[open].p1,&temp1,sizeof(stepInfo));
    memcpy(&Q[open].p2,&temp2,sizeof(stepInfo));
    Q[open].pre = &Q[close];
    Q[open].cnt = Q[close].cnt+1;
    if(hasReachedPeak(Q[open].p1,Q[open].p2))
    {
     reachPeak = true;
     last = &Q[open];
     continue;
    }
    bool duplicate = false;
    for(int i=0;i<open&&!duplicate;i++)
     duplicate = duplicateNode(Q[i],Q[open]);
    if(duplicate)
     open--;
   }
   //左边人向左,右边人向左
   left = 1;
   memcpy(&temp1,c1,sizeof(stepInfo));
   memcpy(&temp2,c2,sizeof(stepInfo));
   temp1.l=temp1.r-1;
   temp2.l=temp2.r-1;
   if(temp1.l>=leftBound&&temp2.l>=leftBound)
   {
    ascending = !coordinates[temp2.l].peak&&coordinates[temp2.r].peak;
    f21(left,ascending,temp1,temp2);
    open++;
    memcpy(&Q[open].p1,&temp1,sizeof(stepInfo));
    memcpy(&Q[open].p2,&temp2,sizeof(stepInfo));
    Q[open].pre = &Q[close];
    Q[open].cnt = Q[close].cnt+1;
    if(hasReachedPeak(Q[open].p1,Q[open].p2))
    {
     reachPeak = true;
     last = &Q[open];
     continue;
    }
    bool duplicate = false;
    for(int i=0;i<open&&!duplicate;i++)
     duplicate = duplicateNode(Q[i],Q[open]);
    if(duplicate)
     open--;
   }
  }
 }
 //printf("reachPeak=%d/n",reachPeak);
 if(reachPeak)
 {
  printf("%d/n",last->cnt);
  backtrack(last);
 }
}
static void backtrack(NodeInfo * s)
{
 if(s==NULL)return;
 backtrack(s->pre);
 stepInfo &l = s->p1;
  stepInfo &r = s->p2;
 int deltax,deltay;
 bool ascending;
 float lx,ly,rx,ry;
 //printf("%d %d %d %d/n",l.l,l.r,r.l,r.r);
 if(l.l==l.r)
 {
  lx = (float)coordinates[l.l].x;
  ly = (float)coordinates[l.r].y;
 }
 else
 {
  int y = coordinates[r.l].y;
     ascending = !coordinates[l.l].peak&&coordinates[l.r].peak;
  if(ascending)
  {
   deltay = coordinates[l.r].y - coordinates[l.l].y;
   deltax = coordinates[l.r].x -coordinates[l.l].x;
   float x = (coordinates[r.l].y-coordinates[l.l].y)*(float)deltax/deltay+coordinates[l.l].x;
   lx = x;
   ly = (float)y;
  }else
  {
   deltay = coordinates[l.l].y - coordinates[l.r].y;
   deltax = coordinates[l.r].x -coordinates[l.l].x;
   float x = -(coordinates[r.l].y-coordinates[l.r].y)*(float)deltax/deltay+coordinates[l.r].x;
   lx = x;
   ly = (float)y;
  }
 }
 if(r.l==r.r)
 {
  rx = (float)coordinates[r.l].x;
  ry = (float)coordinates[r.r].y;
 }
 else
 {
  int y = coordinates[l.l].y;
     ascending = !coordinates[r.l].peak&&coordinates[r.r].peak;
  if(ascending)
  {
   deltay = coordinates[r.r].y - coordinates[r.l].y;
   deltax = coordinates[r.r].x -coordinates[r.l].x;
   float x = (coordinates[l.l].y-coordinates[r.l].y)*(float)deltax/deltay+coordinates[r.l].x;
   rx = x;
   ry = (float)y;
  }else
  {
   deltay = coordinates[r.l].y - coordinates[r.r].y;
   deltax = coordinates[r.r].x -coordinates[r.l].x;
   float x = -(coordinates[l.l].y-coordinates[r.r].y)*(float)deltax/deltay+coordinates[r.r].x;
   rx = x;
   ry = (float)y;
  }
 }
 printf("%.2f %.2f %.2f %.2f/n",lx,ly,rx,ry);
}
//人c1在山谷,人c2在山腰
static void f01(int left,bool ascending_2,stepInfo &c1,stepInfo &c2)
{
 stepInfo tc1,tc2;
 coordinateInfo *n1,*n2,*n3,*n4;
 int l1,r1,l2,r2;
 l1 = c1.l;
 r1 = c1.r;
 l2 = c2.l;
 r2 = c2.r;
 n1 = &coordinates[l1];
 n2 = &coordinates[r1];
 n3 = &coordinates[l2];
 n4 = &coordinates[r2];
 memset(&tc1,0,sizeof(stepInfo));
 memset(&tc2,0,sizeof(stepInfo));
 if(!left)
 {
  //站在山谷的向右上升
  if(ascending_2)
  {
   //右边人处在上升坡
   if(n2->y<n4->y)
   {
    //人c1所在的山峰低于人c2所在山峰
    tc1.l= tc1.r = r1;
    tc2.l = l2;
    tc2.r = r2;
   }else if(n2->y>n4->y)
   {
    //人c1所在的山峰高于人c2所在山峰
    tc1.l = l1;
    tc1.r = r1;
    tc2.l = tc2.r = r2;
   }else
   {
    //人c1所在的山峰与人c2所在山峰一样高
    tc1.l = tc1.r = r1;
    tc2.l = tc2.r = r2;
   }
  }else
  {
   //右边人处在下降坡
   if(n2->y<n3->y)
   {
    //人c1所在的山峰低于人c2所在山峰
    tc1.l = tc1.r = r1;
    tc2.l = l2;
    tc2.r = r2;
   }else if(n2->y>n3->y)
   {
    //人c1所在的山峰高于人c2所在山峰
    tc1.l = l1;
    tc1.r = r1;
    tc2.l = tc2.r = l2;
   }else
   {
    //左边人所在的山峰与右边人所在山峰一样高
    tc1.l = tc1.r = r1;
    tc2.l = tc2.r = l2;
   } 
  }/*if ascending_2*/
 }else
 {
  //站在山谷的向左上升
  ascending_2 = coordinates[l2].peak==false&&coordinates[r2].peak==true;
  n1 = &coordinates[l1];
  n2 = &coordinates[r1];
  n3 = &coordinates[l2];
  n4 = &coordinates[r2];
  if(ascending_2)
  {
   //右边人处在上升坡
   if(n1->y<n4->y)
   {
    //人c1所在的山峰低于人c2所在山峰
    tc1.l = tc1.r = l1;
    tc2.l = l2;
    tc2.r = r2;
   }else if(n1->y>n4->y)
   {
    //人c1所在的山峰高于人c2所在山峰
    tc1.l = l1;
    tc1.r = r1;
    tc2.l = tc2.r = r2;
   }else
   {
    //人c1所在的山峰与人c2所在山峰一样高
    tc1.l = tc1.r = l1;
    tc2.l = tc2.r = r2;
   }
  }else
  {
   //右边人处在下降坡
   if(n1->y<n3->y)
   {
    //人c1所在的山峰低于人c2所在山峰
    tc1.l = tc1.r = l1;
    tc2.l = l2;
    tc2.r = r2;
   }else if(n1->y>n3->y)
   {
    //人c1所在的山峰高于人c2所在山峰
    tc1.l = l1;
    tc1.r = r1;
    tc2.l = tc2.r = l2;
   }else
   {
    //左边人所在的山峰与右边人所在山峰一样高
    tc1.l = tc1.r = l1;
    tc2.l = tc2.r = l2;
   } 
  }/*if ascending_2*/
 }/*if !left*/
 memcpy(&c1,&tc1,sizeof(stepInfo));
 memcpy(&c2,&tc2,sizeof(stepInfo));
}
//人c1在山峰,人c2在山腰
static void f21(int left,bool ascending_2,stepInfo &c1,stepInfo &c2)
{
 stepInfo tc1,tc2;
 coordinateInfo *n1,*n2,*n3,*n4;
 int l1,r1,l2,r2;
 l1 = c1.l;
 r1 = c1.r;
 l2 = c2.l;
 r2 = c2.r;
 n1 = &coordinates[l1];
 n2 = &coordinates[r1];
 n3 = &coordinates[l2];
 n4 = &coordinates[r2];
 memset(&tc1,0,sizeof(stepInfo));
 memset(&tc2,0,sizeof(stepInfo));
 if(!left)
 {
  //站在山峰的向右下降
  if(ascending_2)
  {
   //人c2处在上升坡
   if(n2->y>n3->y)
   {
    //人c1所在的山谷高于人c2所在山谷
    tc1.l = tc1.r = r1;
    tc2.l = l2;
    tc2.r = r2;
   }else if(n2->y<n3->y)
   {
    //人c1所在的山谷低于人c2所在山谷
    tc1.l = l1;
    tc1.r = r1;
    tc2.l = tc2.r = l2;
   }else
   {
    //人c1所在的山谷与人c2所在山谷一样高
    tc1.l = tc1.r = r1;
    tc2.l = tc2.r = l2;
   }
  }else
  {
   //人c2处在下降坡
   if(n2->y>n4->y)
   {
    //人c1所在的山谷高于人c2所在山谷
    tc1.l = tc1.r = r1;
    tc2.l = l2;
    tc2.r = r2;
   }else if(n2->y<n4->y)
   {
    //人c1所在的山谷低于人c2所在山谷
    tc1.l = l1;
    tc1.r = r1;
    tc2.l = tc2.r = r2;
   }else
   {
    //左边人所在的山峰与右边人所在山峰一样高
    tc1.l = tc1.r = r1;
    tc2.l = tc2.r = r2;
   } 
  }/*if ascending_2*/
 }else
 {
  //人c1的向左下降
  if(ascending_2)
  {
   //人c2处在上升坡
   if(n1->y>n3->y)
   {
    //人c1所在的山谷高于人c2所在山谷
    tc1.l = tc1.r = l1;
    tc2.l = l2;
    tc2.r = r2;
   }else if(n1->y<n3->y)
   {
    //人c1所在的山谷低于人c2所在山谷
    tc1.l = l1;
    tc1.r = r1;
    tc2.l = tc2.r = l2;
   }else
   {
    //人c1所在的山谷与人c2所在山谷一样高
    tc1.l = tc1.r = l1;
    tc2.l = tc2.r = l2;
   }
  }else
  {
   //人c2处在下降坡
   if(n1->y>n4->y)
   {
    //人c1所在的山谷高于人c2所在山谷
    tc1.l = tc1.r = l1;
    tc2.l = l2;
    tc2.r = r2;
   }else if(n1->y<n4->y)
   {
    //人c1所在的山谷低于人c2所在山谷
    tc1.l = l1;
    tc1.r = r1;
    tc2.l = tc2.r = r2;
   }else
   {
    //左边人所在的山峰与右边人所在山峰一样高
    tc1.l = tc1.r = l1;
    tc2.l = tc2.r = r2;
   } 
  }/*if ascending_2*/
 }/*if !left*/
 memcpy(&c1,&tc1,sizeof(stepInfo));
 memcpy(&c2,&tc2,sizeof(stepInfo));
}

inline bool hasReachedPeak(stepInfo &s1,stepInfo &s2)
{
 return s1.l==summit&&s1.r==summit&&s2.l==summit&&s2.r==summit;
}
inline bool duplicateStepInfo(stepInfo &s1,stepInfo &s2)
{
 return s1.l==s2.l&&s1.r==s2.r;
}
inline bool duplicateNode(NodeInfo &s1,NodeInfo &s2)
{
 return duplicateStepInfo(s1.p1,s2.p1)&&duplicateStepInfo(s1.p2,s2.p2);
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值