全排序问题

排版题.输出排列成菱形的字母

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值