"Now I will show you the first problem." feng5166 says, "Given a sequence of number 1 to N, we define that 1,2,3...N-1,N is the smallest sequence among all the sequence which can be composed with number 1 to N(each number can be and should be use only once in this problem). So it's easy to see the second smallest sequence is 1,2,3...N,N-1. Now I will give you two numbers, N and M. You should tell me the Mth smallest sequence which is composed with number 1 to N. It's easy, isn't is? Hahahahaha......"
Can you help Ignatius to solve this problem?
题意:求数列1~n的第m个全排列。
题解:用STL里的next_permutation和DFS都可解,但时间复杂度就相去甚远了。
STL:耗时31ms
#include <cstdio> #include <algorithm> using namespace std; int arr[1002]; int main() { int n, m, i; while(scanf("%d%d", &n, &m) != EOF){ for(i = 0; i < n; ++i) arr[i] = i + 1; while(--m) next_permutation(arr, arr + n); for(i = 0; i < n; ++i) if(i != n - 1) printf("%d ", arr[i]); else printf("%d\n", arr[i]); } return 0; }DFS:耗时390ms
#include <stdio.h> #include <string.h> #define maxn 1002 int vis[maxn], n, m, arr[maxn], count, ok; void PRINT() { for(int i = 1; i <= n; ++i) if(i != n) printf("%d ", arr[i]); else printf("%d\n", arr[i]); } void DFS(int k) { if(k > n) return; for(int i = 1; i <= n; ++i){ if(!vis[i]){ vis[i] = 1; arr[k] = i; if(k == n && m == ++count){ PRINT(); ok = 1; return; } DFS(k + 1); vis[i] = 0; if(ok) return; } } } int main() { while(scanf("%d%d", &n, &m) != EOF){ memset(vis, 0, sizeof(vis)); ok = count = 0; DFS(1); } return 0; }