首页 > 其他 > 详细

连接数

时间:2017-01-24 17:49:44      阅读:205      评论:0      收藏:0      [点我收藏+]
  1 #include<iostream>
  2 using namespace std;
  3 
  4 #define SIZE  9
  5 #define MAXLEN  6
  6 int data[SIZE][MAXLEN];
  7 int numberLen[SIZE];//某一行有几位
  8 int overlapLen[SIZE+1][SIZE+1];//某两位数的重叠长度
  9 int maxLen=0;
 10 int used[SIZE];
 11 
 12 void IToA(int N,int row)//数字转数组,并记录长度
 13 {
 14   int  tmp=N;
 15   int n=0;
 16   while(tmp){   //统计位数
 17     n++;
 18     tmp/=10;
 19   }
 20   numberLen[row]=n;  //位数信息放进数组
 21   tmp=N;
 22   for(int j=n-1;j>=0;j--)
 23   {
 24    data[row][j]=tmp%10;
 25    tmp/=10; 
 26   }
 27 }
 28 
 29 void getOverlapLen(int i,int j)//计算两个数字的最小重叠长度,分前后,i在前,j在后
 30 {
 31   for(int len=1;len<=numberLen[i]&&len<=numberLen[j];len++)//遍历重合长度
 32   {
 33         int flag=1;//标志位
 34         for(int m=numberLen[i]-len,n=0;m<numberLen[i]&&n<numberLen[j];m++,n++)
 35         {
 36               if(data[i][m]!=data[j][n])
 37               {
 38                  flag=0;
 39                  break;
 40               }
 41         }
 42         if(flag)
 43         {
 44               overlapLen[i][j]=len;
 45               break;
 46         }
 47   }
 48 }
 49 
 50 void getMaxLen(int step,int numbers,int curLen,int remainingLen,int preNumber)
 51 {
 52  if(step==numbers)  return ;//出口
 53  if(curLen+remainingLen-(numbers-step)+1<=maxLen)  return;//预测长度剪枝
 54 
 55    for(int i=0;i<numbers;i++)//全排列过程
 56    {
 57       if(!used[i])
 58       {
 59         used[i]=1;
 60         int tmpLen=curLen;
 61 
 62         //关键代码,必须有
 63         if(overlapLen[i][preNumber]==0&&step!=0)//只处理连接成功的情况
 64         {
 65          used[i]=0;//注意占位及恢复
 66          continue;
 67         }
 68 
 69         curLen +=numberLen[i]-overlapLen[i][preNumber];
 70         if(maxLen<curLen) 
 71             maxLen=curLen;
 72         getMaxLen(step+1,numbers,curLen,remainingLen-numberLen[i],i);//全排列的同时进行dfs
 73         used[i]=0;  //数据恢复
 74         curLen=tmpLen;
 75       }
 76    }
 77 }
 78 
 79 int main()
 80 {
 81   freopen("input.txt","r",stdin);
 82   int nTc;
 83   cin>>nTc;
 84   while(nTc--)
 85   {
 86    int N;
 87    cin>>N;
 88    
 89    //全局变量初始化
 90    maxLen=0;
 91    for(int i=0;i<SIZE;i++)
 92    {
 93      used[i]=0;
 94      for(int j=0;j<MAXLEN;j++)   
 95      {
 96         data[i][j]=0;     
 97      }
 98    }
 99    for(int i=0;i<=SIZE;i++)
100    {
101      for(int j=0;j<=SIZE;j++)   
102      { 
103         overlapLen[i][j]=0;
104      }
105    }
106 
107    int temp;  
108    int totalLen=0;//N个数总共有多少位
109    for(int i=0;i<N;i++)
110    {
111      cin>>temp;
112      IToA(temp,i);
113      totalLen+=numberLen[i];
114    }
115 
116     //求重合长度,数据预处理,可以处理极端的case
117     for(int i=0;i<N;i++)
118     {
119          for(int j=0;j<N;j++)
120          {
121              if(i!=j)      
122                  getOverlapLen(i,j);
123          }
124     }
125 
126     getMaxLen(0,N,0,totalLen,SIZE); //step=0时,要求chongdie[i][prenum]=0
127     cout<<maxLen<<endl;
128   }
129   return 0;
130 }

 

连接数

原文:http://www.cnblogs.com/jintg/p/6347411.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!