#include <stdio.h> #define br printf(" "); int ans=0; char el[502]; int confirm(int i,int k) //往回比较,如果元素有相同跳过此情况 { if(i>k) { while(i>k) { if(el[i]==el[k]) return 0; k++; } } return 1; } void op(int n) { ans++; int j; for(j=0;j<=n;j++) printf("%c",el[j]); br } void perm(int n,int k) //n代表当前距离分配结束的个数(数组模式,-1) k代表当前元素的位置 { int i,r; if(n==k) op(n); //如果两个数已经达到相等 输出 else for(i=k;i<=n;i++) //从当前数组元素开始一直到末尾,逐个进行交换 if(confirm(i,k))//根据返回结果进行交换 { r=el[i];el[i]=el[k];el[k]=r; perm(n,k+1); //推进k的一位 r=el[i];el[i]=el[k];el[k]=r; } } int main() { int n,i; scanf("%d",&n); getchar(); for(i=0;i<n;i++) scanf("%c",&el[i]); //以上是普通的输入环节 perm(n-1,0); printf("%d",ans); return 0; }
原谅我的恶趣味哈哈哈。
整个思路是这样的:
a a c c
0 1 2 3
首先和自己交换一次
a a c c
a a c c 后方字母乱序
然后递归下去,不停地把往后每个字符都代到当前位置寻找下一步情况。
c a a c
如果不是在和自己交换,那么检测一下是否在之前交换过同样的元素。比如:
a b c d e f e h
a b c e d f e h 后方字母乱序
如果下一次和下一个e交换,那么效果和第一个e相同,都是后面顺序不管,abce往下找。
a b c d e f e h
a b c e e f d h
检测要从前往后找,这样能找到第一位的
a b c d e f e h
k i
a b c d e f e h
k i 相等,跳过此情况
慢慢体会吧。应该很清楚了