题目: https://ac.nowcoder.com/acm/contest/5646/H

#include <stdio.h>
#include <string.h>

// 指针与二维数组 https://www.cnblogs.com/jszl-red-leaves/p/11218465.html

int main()
{
    int n,i,j;
    int len=0;

    scanf("%d",&n);
    char s[n][1000];
    char *p[n]; // 内含 n 个指针变量(指向char类型)的数组([]优先级高于*)
    char *tmp;
    for(i=0;i<n;i++){
        scanf("%s",s[i]); // s[i]即一维数组名(第i行首元素地址)
        p[i] = s[i]; // 用指针存储每一行首元素地址,便于后续操作
        // 直接在接下来的排序中将p换为s会出现编译错误,
        // 总之用指针来操作简洁明了,方便可行
    }
    // 排序指针而非字符串,即改变指针指向,从而根据 按原始字符串排序后的指针指向 输出排序后的字符串
    // 把p重新排列,而不改变s;保留了s中的原始数据;不需要strcpy(参考 C primer plus P360)
    // 排序,注意每个字符串都要在整行中合适的位置,而不是单单与相邻元素比较!!
    for(i=0;i<n-1;i++){ // 注意应为n-1,因为下一层循环从i+1开始,避免越界
        for(j=i+1;j<n;j++){ // 排完第i趟,则 i位置 上的已经ok了(与 全部 未排序的进行比较,若i位置上的不符合,则交换直至符合要求,若已经符合要求,则不变动)
            if(strcmp(p[i],p[j])>0){ // 若p[i]大,则交换,否则不交换,即从小到大
                tmp = p[i];
                p[i] = p[j];
                p[j] = tmp;
            }
        }
    }

    for(i=0;;i++){
        printf("%s",p[i]);
        if(i==n-1){
            printf("\n");
            break;
        }
        printf(" ");
    }

    return 0;
}