公路重建问题

摘要:所谓公路重建,其实质上就是给定一个点之间距离的集合,求解出一个可能的点集.

这里写图片描述

(1)基本思路:

[1]可以知道,距离最大的一定是从第一个点到最后一个点的.那么我们将第一个点的坐标定为0,最后一个点的坐标定为10.

公路重建问题_第1张图片

[2]接下来删除集合中的距离10,那么该集合就是由N-1个点构成的距离集合.接下来,再去最大的距离,很显然,距离8可以是一个点到x0的距离,也可以是点到x6的距离.这时候有两种情况,因此我们要进行回溯算法来试探可能的解.

[3]首先试探点x1 = 8,的情况,删除所有的x1与现有点集中所有点对应的距离,比如D = 8,D = 2.如果在删除的时候发现没有对应的距离,就得出这个组合不行,试探点在右边的情况.如果还是不行,就返回上次试探的结果,将上一次的试探复原.进行另外的试探.

#include "stdafx.h"
#include "math.h"
#include "malloc.h"
#include "string.h"
#define False -1
#define True 1
int index[15];
int Find(int distance,int D[],int N)
{
    for (int i = 0;i<= N-1;i++)
    {
        if (distance == D[i])
            return i;
    }
    return -1;
}
int FindMax(int D[],int N)
{
    int i ;
    for ( i = N-1;i>=0;i--)
    {
        if (D[i] != -1)
            return D[i];
    }
    if(i==-1)
        return -1;
}

 int Place(int X[],int D[],int N,int Left,int Right)
 {
     int Dmax,Found = False;
     int *Copy = (int *)malloc(sizeof(int)*15);
     memcpy(Copy,D,sizeof(int)*15);
     int mark = True,Index,M = N*(N-1)/2;
     if(Left>Right)
     {
         return True;
     }
     Dmax = FindMax(D,M);
     //判断Dmax对应的点是在左边还是右边
     for (int i = 0;i<=N-1;i++)
     {
         Index = Find(abs(X[i] - Dmax),D,M);
         if((i<Left||i>Right)&&(Index==-1))
         {
             mark = False;
             break;
         }
         else if ((i<Left||i>Right))
             D[Index] = -1;//暂时删除
     }
     if (mark == True)//所有已知的|x[i] - Dmax都在D中
     {
         X[Right] = Dmax;
         Found = Place(X,D,N,Left,Right-1);
     }
     memcpy(D,Copy,sizeof(int)*15);

     mark = True;
      for (int i = 0;i<=N-1;i++)
     {
         Index = Find(abs(X[N-1] - X[i] - Dmax),D,M);
         if((i<Left||i>Right)&&(Index==-1))//在检查时应该将检测到的暂时删除
             //避免x被测到2次
         {
             mark = False;
             break;
         }
         else if ((i<Left||i>Right))
             D[Index] = -1;
     }
     if (Found == False&&mark == True)
     {
         X[Left] = abs(X[N-1] - Dmax);
         Found = Place(X,D,N,Left+1,Right);
     }
     memcpy(D,Copy,sizeof(int)*15);
     free(Copy);
     return Found;
 }
 int Turnpike(int X[],int D[],int N )
 {
     int M = N*(N-1)/2;
     int Index;
     X[0] = 0;
     X[N-1] =  D[M-1];
     X[N-2] = D[M-2];
     D[M-1] = -1;
     D[M-2] = -1;
    Index=Find(abs(X[N-1]-X[N-2]),D,N);//标记|x[N-1] - x[N-2]|在D的下标
     if (Index!=-1)//X[N-1] - X[N-2] 在D里面
     {

           D[Index] = -1;    //将X[N] - X[N-1]从D移除
           return Place(X,D,N,1,N-3);
     }
     else return False;
 }
int _tmain(int argc, _TCHAR* argv[])
{
    int X[6];
    int D[15] = {1,2,2,2,3,3,3,4,5,5,5,6,7,8,10};
    Turnpike(X,D,6);
    return 0;
}

你可能感兴趣的:(公路重建问题)