题目:
给出N个数组(2<=N<=9),每个数字长度是2-6位,每一位是1-4。如果某个数字尾数和其他的数头相同,即可拼接成一个新的 数字。如:123,234 可以拼接成1234。
连接成的新数字可以和其他未使用过的数字再按照规则连接成为新的数字。如:123,141,234可以连接成1234,14123和141234
注:case里面可能只有一部分数字可以连接:222 222可以形成22222,也可以形成2222
求:能够连接成的最大数字是几位。
case:
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
---------------------------------------------------------
import java.util.Scanner;
public class Test {
// 拼接成的数字的最大长度
static int maxLen = 0;
public static void main(String[] args) {
// long start = System.currentTimeMillis();
// 将case输入
// Scanner in = new Scanner(new
// FileInputStream("C:\\Users\\john\\Desktop\\sumsung_test\\Test30_1215_zhenti.txt"));
Scanner in = new Scanner(System.in);
// case的个数
int CN = in.nextInt();
int allcase[][] = new int[CN][];
for (int j = 0; j < CN; j++) {
int len = in.nextInt();
int perdata[] = new int[len];
for (int i = 0; i < perdata.length; i++) {
perdata[i] = in.nextInt();
}
allcase[j] = perdata;
}
// for循环遍历每个case
for (int i = 0; i < allcase.length; i++) {
// 每次case都初始化maxLen的值
maxLen = 0;
// 新建一维数组存放case
int[] data = allcase[i];
// 调用函数
DFS(data, 0, data.length - 1);
// 输出结果
System.out.println(maxLen);
}
// long end = System.currentTimeMillis();
// 程序运行时间
// System.out.println((end - start) + "MS");
}
// 用递归全排列数组的顺序
public static void DFS(int[] data, int start, int end) {
// 迭代结束条件
if (start == end) {
// 插入函数:(每排列出一种组合就调用函数)依次进行拼接
int nowlen = toMosaic(data);
// 更新maxLen的值
if (nowlen > maxLen) {
maxLen = nowlen;
}
} else {
// 数组内元素进行组合的全排列(套路)
for (int i = start; i <= end; i++) {
int temp = data[start];
data[start] = data[i];
data[i] = temp;
// 进行迭代
DFS(data, start + 1, end);
// 将数组还原
temp = data[start];
data[start] = data[i];
data[i] = temp;
}
}
}
// 将data数组中的元素从前到后一次进行拼接
public static int toMosaic(int[] data) {
// 表示目前拼接成的长度
int numLength = 0;
// 遍历数组
for (int i = 0; i < data.length - 1; i++) {
// 标志位,该值为0表示不能进行拼接
int temp = 0;
// 将数组元素进行处理,方便拼接
int[] data1 = numToArr(data[i]);
int[] data2 = numToArr(data[i + 1]);
int[] tail = tailArr(data1);
int[] head = headArr(data2);
// 一次比较头数组和尾数组,看能否进行拼接
for (int n = 0; n < tail.length && n < head.length; n++) {
// 如果可以进行拼接
if (tail[n] == head[n]) {
if (i == 0) {
// 第一个元素和第二个元素进行拼接的长度计算方法
numLength = numLength + (n + 1) + (tail.length - 1 - n) + (head.length - 1 - n);
} else {
// 其他元素拼接的长度拼接方法
numLength = numLength + (head.length - 1 - n);
}
// 将标志位置1, 表示可以进行拼接
temp = 1;
break;// 直接break掉,因为已经是最大的长度
}
}
// 如果不能拼接
if (temp == 0 && i == 0) {
return data1.length;// 第一个元素和第二个元素不能进行拼接
} else if (temp == 0 && i != 0) {
return numLength;// 其他情况
}
}
// 如果全部可以拼接,返回长度
return numLength;
}
// 获取头数-数组
public static int[] headArr(int[] data2) {
int[] head = new int[data2.length];
int sum = 0;
for (int i = 0; i < data2.length; i++) {
head[i] = sum * 10 + data2[i];
sum = head[i];
}
return head;
}
// 获取尾数-数组
public static int[] tailArr(int[] data1) {
int[] tail = new int[data1.length];
int ind = 0;
int minus = 10;
int sum = data1[data1.length - 1];
for (int i = data1.length - 1; i >= 0; i--) {
if (i == data1.length - 1) {
tail[ind++] = data1[i];
} else {
tail[ind++] = data1[i] * minus + sum;
sum = tail[ind - 1];
minus *= 10;
}
}
return tail;
}
// 将一个十进制数转换成为一维数组
public static int[] numToArr(int num) {
int[] arr;
int count = 0;
int temp = num;
while (temp != 0) {
temp = temp / 10;
count++;
}
arr = new int[count];
for (int i = arr.length - 1; i >= 0; i--) {
arr[i] = num % 10;
num = num / 10;
}
return arr;
}
}