给出N个数字(2=<N<=9),每个数字长度是2-6位,每一位是1到4,如果某个数字尾数和其他的数字的数头相同,即可连成一个新的数字,
如123,234可以连成1234,连成的新的数字可以和其他未使用过的数字再按照规则连接成为新的数字
如:123,141,234,可以连成1234,14123和141234
注意:case 里面可能只有一部分数字可以连接222 222 可以形成22222,也可以形成2222
求能够连接的最大数字是几位??
input.txt
5
3
123
141
234
2
24
123
4
343
2433
2213
3333
8
434121
441
4234
223142
23413
14342
224
234
9
221111
212111
122111
121232
211112
122112
211111
211121
121122
程序:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 9
#define MAXLEN 6
int data[SIZE][MAXLEN];
int numberLen[SIZE];
int overlapLen[SIZE+1][SIZE+1];
void IToA(int N,int row){//数字转数组,并记录长度,
int tmp = N;
int i = 0;
while(tmp){
i++;
tmp/=10;
}
numberLen[row] = i;
tmp = N;
for(int j = i-1;j>= 0;j--){
data[row][j] = tmp % 10;
tmp /= 10;
}
}
void getOverlapLen(int i,int j){//计算两个数字的最小重叠长度
for(int len = 1;len<=numberLen[i]&& len <= numberLen[j];len++){
int match =1;
for(int m = numberLen[i] - len, n=0;m<numberLen[i] && n < numberLen[j];m++,n++){
if(data[i][m] != data[j][n]){
match = 0;
break;
}
}
if(match){
overlapLen[i][j] = len;
break;
}
}
}
int maxLen = 0;
int used[SIZE];
void getMaxLen(int step,int numbers,int curLen,int remainingLen,int preNumber){//getMaxLen(0,N,0,totalLen,SIZE);
if(step == numbers){//出口
return;
}
if(curLen + remainingLen - numbers + step +1 <= maxLen){//预测长度剪枝
return;
}
for(int i = 0;i<numbers;i++){
if(!used[i]){
used[i] = 1;
int tmpLen = curLen;
if(overlapLen[i][preNumber] == 0 && step != 0){//只处理连接成功的情况
used[i] = 0;//注意占位及恢复
continue;
}
curLen += numberLen[i] - overlapLen[i][preNumber];
if(maxLen < curLen){
maxLen = curLen;
}
getMaxLen(step + 1,numbers,curLen,remainingLen - numberLen[i],i);
used[i] = 0;
curLen = tmpLen;
}
}
}
void main(){
freopen("input.txt","r",stdin);
int nTc;
scanf("%d",&nTc);
for(int tc = 0;tc < nTc; tc++){
int N;
scanf("%d",&N);
maxLen = 0;
for(int i = 0;i<N;i++){
used[i] = 0;
for(int j = 0;j<N;j++){
data[i][j] = 0;
overlapLen[i][j] = 0;
}
}
int temp;
int totalLen = 0;
for(int i = 0;i<N;i++){
scanf("%d\n",&temp);
IToA(temp,i);
totalLen += numberLen[i];
}
for(int i =0;i<N;i++){
for(int j = 0;j<N;j++){
if(i != j){
getOverlapLen(i,j);
}
}
}
getMaxLen(0,N,0,totalLen,SIZE);
printf("%d\n",maxLen);
}
}