九度OJ 1120:全排列 (DFS)

时间限制:1 秒

内存限制:32 兆

特殊判题:

提交:4471

解决:1139

题目描述:

给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。
我们假设对于小写字母有'a' < 'b' < ... < 'y' < 'z',而且给定的字符串中的字母已经按照从小到大的顺序排列。

输入:

输入只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间。

输出:

输出这个字符串的所有排列方式,每行一个排列。要求字母序比较小的排列在前面。字母序如下定义:
已知S = s1s2...sk , T = t1t2...tk,则S < T 等价于,存在p (1 <= p <= k),使得
s1 = t1, s2 = t2, ..., sp - 1 = tp - 1, sp < tp成立。

样例输入:
abc
样例输出:
abc
acb
bac
bca
cab
cba
提示:

每组样例输出结束后要再输出一个回车。

来源:
2008年北京大学图形实验室计算机研究生机试真题

思路:

DFS可解。注意返回时恢复原来状态。


代码:

#include <stdio.h>
#include <string.h>
//#include <sys/time.h>
//#include <time.h>
 
#define N 7 
 
char s[N];
int n;
 
void array(int begin)
{
    int i, j;
    if (begin == n-1)
    {
        //for (j=0; j<n; j++)
        //    printf("%c", s[j]);
        //printf("\n");
        printf("%s\n", s);
        return;
    }
 
    //char a[N];
    //for (i=0; i<begin; i++)
    //  a[i] = s[i];
    char c;
    for (i=begin; i<n; i++)
    {
        c = s[i];
        for (j=i; j>begin; j--)
            s[j] = s[j-1];
        s[begin] = c;
        //printf("s=%s, begin=%d\n", s, begin);
        array(begin+1);
        c = s[begin];
        for (j = begin; j < i; j++)
            s[j] = s[j+1];
        s[j] = c;
        //printf("s=%s, begin=%d\n", s, begin);
    }
}
 
int main(void)
{
    //struct timeval tv;
 
    while (scanf("%s", s) != EOF)
    {
        //gettimeofday(&tv, NULL);
        //printf("%d:%d\n", tv.tv_sec, tv.tv_usec);
        n = strlen(s);
        array(0);
        printf("\n");
        //gettimeofday(&tv, NULL);
        //printf("%d:%d\n", tv.tv_sec, tv.tv_usec);
    }
 
    return 0;
}
 
/**************************************************************
    Problem: 1120
    User: liangrx06
    Language: C
    Result: Accepted
    Time:340 ms
    Memory:912 kb
****************************************************************/


posted on 2015-10-23 23:02  梁山伯  阅读(305)  评论(0编辑  收藏  举报

导航