1 int a[N] //默认排序 2 void find_next() // 产生下一个字典序 3 { 4 int pos; 5 for (int i=n-1;i>=1;i--) 6 if (a[i]<a[i+1]) { 7 pos=i; 8 break; 9 } 10 11 int tmp=100; 12 int k_p; 13 // cout<<pos<<endl; 14 for (int i=n;i>=pos+1;i--) 15 if (a[i]>a[pos]) 16 if (a[i]<tmp) { 17 tmp=a[i]; 18 k_p=i; 19 } 20 21 swap (a[pos],a[k_p]); 22 reverse (a+pos+1,a+n+1); 23 return ; 24 }
我发现一个有趣的现象。。。。(暴力发现的; 233)
对于一个置换 (x1,x2,x3......xn)
定义: f(x) =a[x]
例如 【2,1,3,4】 f(2)=a[2]=1;
定义: f^2(x)=f(f(x))
那么f^n(x)=x (! 当且仅当f^n(x)=x)置换的数目为(n-1)!
好像记得离散数学有讲,以后有空证明一下。233
暴力发现的代码
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=107; 4 int a[N]; 5 int n; 6 int sum; 7 bool isok () { 8 for (int i=1;i<=n;i++) { 9 int tmp=a[i]; 10 for (int j=1;j<n;j++) { 11 tmp=a[tmp]; 12 if (tmp==a[i]) return 0; 13 } 14 } 15 return 1; 16 } 17 void find_next() // ²úÉúÏÂÒ»¸ö×ÖµäÐò 18 { 19 int pos; 20 for (int i=n-1;i>=1;i--) 21 if (a[i]<a[i+1]) { 22 pos=i; 23 break; 24 } 25 int tmp=100; 26 int k_p; 27 for (int i=n;i>=pos+1;i--) 28 if (a[i]>a[pos]) 29 if (a[i]<tmp) { 30 tmp=a[i]; 31 k_p=i; 32 } 33 34 swap (a[pos],a[k_p]); 35 reverse (a+pos+1,a+n+1); 36 return ; 37 } 38 int main () 39 { 40 while (cin>>n) { 41 sum=0; int m=1; 42 for (int i=1;i<=n;i++) { a[i]=i; m*=i; } 43 if ( isok () ) sum++; 44 for (int i=1;i<m;i++) { 45 find_next(); 46 if ( isok () ) sum++; 47 } 48 cout<<sum<<endl; 49 } 50 return 0; 51 }