排版题.输出排列成菱形的字母
Time Limit:1s Memory Limit:65536k
Total Submit:11734 Accepted:4152
Problem
将一个字符组全排序
Input
一个长度小于10的字符串,该字符串由数字1~9组成。字符不会重复出现。
Output
按数字在输入串中出现的次序从小到大的顺序输出该字符组的全排序
Sample Input
132
Sample Output
1 3 2 1 2 3 3 1 2 3 2 1 2 1 3 2 3 1
C的求解及答案
#include <stdio.h>
#include <string.h>
int main()
{
char input_string[10];
char string_pos[10];
int string_length, i, j, pos, find_again;
scanf("%s", input_string);
string_length = strlen(input_string);
//在内存中,string_pos[] = "54321",但表示的数为"12345"
for(i = 0; i < string_length; i++) string_pos[i] = string_length - 1 - i;
while(string_length > 1){
//因此,需要逆过来输出
for(i = string_length - 1; i >= 0; i--){
putchar(input_string[string_pos[i]]);
if(i > 0) putchar(' ');
}
putchar('/n');
//string_pos[1]对应的表示从倒数第二位开始
pos = 1;
do{
find_again = 0;
//试着加1,判断是否溢出.如果溢出则要回溯
string_pos[pos]++;
if(string_pos[pos] == string_length) find_again = 1;
if(!find_again){ //不溢出,则看看是否新的值已经被使用
do{
for(j = pos + 1; j < string_length; j++)
if(string_pos[pos] == string_pos[j]){ //已经被使用,则再试着加1
string_pos[pos] ++;
if(string_pos[pos] == string_length){ //如果溢出则要回溯
find_again = 1;
goto again;
}else break; //如果不溢出,则看看是否新的值已经被使用,回到上面的do
}
if(j == string_length) goto again; //ok, 新的值未被使用!
}while(1);
}
again:
if(find_again){ //当find_again时,说明找到溢出还是没找到合适的值,则回溯
pos++;
if(pos == string_length) goto bye; //没路可回溯了,可以结束
}
}while(find_again); //当!find_again时,说明找到一个合适的值
//反过来,填最小的值给还未确定的值[pos..0].(可以优化)
for(i = 0; i < string_length; i++){
for(j = string_length - 1; j >= pos; j--){
if(string_pos[j] == i) break;
}
if(j < pos){
pos --;
string_pos[pos] = i;
}
}
}
bye:
return 0;
}
Memory: 32K
Time: 2ms