数字全排列
題意;
從1~9之間順序取N個數字,組成每位數不重復的所有可能的N位數,按從小到大的順序進行編號,當輸入其中的任何一個數M是,能找出該數對應的編號。如:當N = 3,M = 132時,則輸出: [123(1), 132(2), 213(3), 231(4), 312(5), 321(6)]——> X = 2
Input
輸入只有一行,兩個正整數N和M(1 ≤ N ≤ 9,1 ≤ K ≤ 987654321),之間用一個空格分隔開。
Output
輸出對應的編號X。
Sample Input
3 132
Sample Output
2
這類題 其實就是讓我們來對數的全排列
| 首先簡單的說一下思路: 例如 數字 3142 他前面一定有1和2 開頭之后剩下三個數的全排列 也就是階乘;所以一定會用到階乘不妨就寫一個階乘函數,當然這個階乘函數引入的不是這個位的位數 而是 這個位數-1的階乘 。這一點應該很好理解。之后就來研究該怎么處理這個階乘。 3的話,在它之前一定有1,2的全排也就是階乘乘以二。 |
| 中間一點錯誤:一開始我是用這個數減一后來考慮到后面就不對了 1先跳過,看4 他要是按這種方法的話就是3種 可是他跟最后一位最多2個數字就2種情況 :42 , 24 ; |
| 正確思路 :找到逆序數也就是比他位數低,而且數值也比這位數小 像 3142 一樣就是2*(3!)*0*(2!)*1*(1)=13; |
方法二: 深搜
深搜這種方法也不用大說直接看代碼吧。
#include<stdio.h>//深度搜索 # include<string.h> int n,loop,vis[100],j,result[100],Count,sign; char str[100]; void DFS(int step) {int i;sign=0;if(step==n+1)//結束{Count+=1;for(i=1;i<=n;i++){if(result[i]==str[i-1]-'0')//判斷找得這個數是不是需要的那個數sign+=1;}if(sign==n)//是這個數loop=Count;//這就是那個數排序后的序號return;}for(i=1;i<=n;i++)//從一看是dfs{if(!vis[i]){vis[i]=1;//標記這個數用過避免重復使用result[step]=i;DFS(step+1);vis[i]=0;//還原}} } int main() {scanf("%d %s",&n,str);memset(vis,0,sizeof(vis));Count=0;sign=0;DFS(1);//從一開始dfsprintf("%d\n",loop);return 0; }方法三:
| 這種方法其實是中用c++中的一種函數next_permutation和prev_permutation 現在還沒大搞懂 ```cpp //第一種方法在algorithm里面有個next_permutation可以實現,排序道理是一樣的 //如果把next_permutation換成prev_permutation,一開始賦值就應是倒序,如:321 # include # include # include using namespace std; int main() { int num,count=0,i; char str[20],s[20]; cin>>num>>str; for(i=0;i |
總結 ;
| 遇到這類題往枚舉,深搜上想好點,畢竟時間復雜度太大 最大8^8 這種好想點 ,再者就是找先規律。當然也不要每個題都能找得到規律,功夫不到家就是白忙活,所以,Fighting!!! |
總結
- 上一篇: SVN Eclipse插件Subclip
- 下一篇: 调用APP市场对自身APP评分及国内各应