一、解题思路
1.核心目的
题目的意思是将几个数首尾拼接在一起,使数的大小最大,所以对于每一位的数我们都要保证最大,假设有1,2,3,4,5个数,最大的数就是54321。因此,我们主要的目的就是找到首位最大的数。
2.如何处理输入
由于我们只需要比较每个数首位数字数字的大小,不需要比较整个数的大小,并且,当遇到首位相同的情况时,还需要逐位比较,所以用字符串处理输入比较好处理。这里,用calloc函数动态分配一个字符二维数组用于储存。
char** num = (char**)calloc(n , sizeof(char*));
for (int i = 0; i < n; i++)
{
num[i] = (char*)calloc(15 , sizeof(char));
}
3.如何找到最大值
这部分也是最难想的,首先在一个字符二维数组中,很容易通过循环找到首位最大的数,但我们找到一个最大值之后,还需要在剩下数中找到下一个最大值,所以需要一个循环嵌套。而剩下的就是如何找到最大值。
1.第一种情况,首位大小
比如,在6和456两个数中,由于6大于4,因此最大的数应该是6,所以对于一串数,哪个数的首位最大,它就在排在第一位,这里我将这个数叫最大值。
2.第二种情况,首位相同
比如,在345与325的比较下,由于第二位的4大于2,所以345要排在前面,所以在这个情况下要逐位比较,同时,这里还有一个很难发现的情况(我也是看了洛谷的测试数据才知道),比如321与32两个数,按照逐位比较是错的,32要在321前面,所以还要考虑是否到了字符串的末尾。最后就是完全相同的两个数的情况,直接取其一个就可以。
4.如何输出
题目要求我们输出最后拼接的数,这里就要请出我们的指针了。首先,在打印一个字符数组时候,通常在printf函数中写的是一个数组名,而数组名就是字符数组首元素地址,首元素不就是找到最大值的关键吗?这也太巧合和。因此,就可以用指针来比较和输出了。如下代码。
int j = 0;
char* max = num[0];
while (j < n)
{
for (int i = 0; i < n; i++)
{
if (*(max + 0) < num[i][0])
{
max = num[i];
}
else if (*(max + 0) == num[i][0]&&max!=num[i])
{
for (int m = 1;; m++)
{
if (*(max + m) == '\0' && num[i][m] == '\0')
{
break;
}
if (*(max + m) < num[i][m]&& num[i][m] != '\0'&& *(max + m) != '\0')
{
max = num[i];
break;
}
else if (*(max+m)=='\0'&&num[i][m]!='\0')
{
if (num[i][m] >= *(max + 0))
{
max = num[i];
break;
}
}
else if (*(max + m) != '\0' && num[i][m] == '\0')
{
if (*(max + m) < num[i][0])
{
max = num[i];
break;
}
}
else if (*(max + m) == num[i][m])
{
continue;
}
else
{
break;
}
}
}
}
printf("%s", max);
*max = '\0';
j++;
}
二、AC代码
#include<stdio.h>
#include<stdlib.h>
int main()
{
int n;
scanf("%d", &n);
int* number = (int*)malloc(n * sizeof(int));
for (int i = 0; i < n; i++)
{
scanf("%d", &number[i]);
}
char** num = (char**)calloc(n , sizeof(char*));
for (int i = 0; i < n; i++)
{
num[i] = (char*)calloc(15 , sizeof(char));
}
for (int i = 0; i < n; i++)
{
sprintf(num[i], "%d", number[i]);
}
int j = 0;
char* max = num[0];
while (j < n)
{
for (int i = 0; i < n; i++)
{
if (*(max + 0) < num[i][0])
{
max = num[i];
}
else if (*(max + 0) == num[i][0]&&max!=num[i])
{
for (int m = 1;; m++)
{
if (*(max + m) == '\0' && num[i][m] == '\0')
{
break;
}
if (*(max + m) < num[i][m]&& num[i][m] != '\0'&& *(max + m) != '\0')
{
max = num[i];
break;
}
else if (*(max+m)=='\0'&&num[i][m]!='\0')
{
if (num[i][m] >= *(max + 0))
{
max = num[i];
break;
}
}
else if (*(max + m) != '\0' && num[i][m] == '\0')
{
if (*(max + m) < num[i][0])
{
max = num[i];
break;
}
}
else if (*(max + m) == num[i][m])
{
continue;
}
else
{
break;
}
}
}
}
printf("%s", max);
*max = '\0';
j++;
}
for (int i = 0; i < n; i++)
{
free(num[i]);
}
free(num);
free(number);
return 0;
}
由于一开始我还没想到用字符串处理最大值,就写了一个二维数组来储存输入,后面用sprintf来转化为字符串,所以一开始可以直接用字符串。