hdu 1027 水+模拟排列

谁借莪1个温暖的怀抱¢ 2022-08-08 14:51 222阅读 0赞

题意:

  1. 给定1~n的序列,求第m小的序列。大小比较按照字符串比较的顺序。

分析:

  1. n个数有n!个排列方式,如果在n里面取出最小的1,那么后面的就有n-1!个序列,按照这个原理,从前往后推,可以得出最后的序列。

代码:

  1. #include <iostream>
  2. #include <cstring>
  3. using namespace std;
  4. int ans[1001],n;
  5. bool f[1001];
  6. int calJc(int k) {
  7. int i , s = 1;
  8. for (i = 1; i <= k; i++)
  9. s = s * i;
  10. return s;
  11. }
  12. void tmj(int k, int m) {
  13. int i, tt, p;
  14. if (k > 0) {
  15. int s = calJc(k - 1);
  16. int t = m / s;
  17. if (m % s != 0) t++;
  18. tt = t;
  19. for (i = 1; i <= n; i++)
  20. if (f[i] == 0) {
  21. t--;
  22. if (t == 0) {
  23. ans[n - k + 1] = i;
  24. f[i] = 1;
  25. break;
  26. }
  27. }
  28. tmj(k - 1, m - (tt - 1) * s);
  29. } else if (m == 0) {
  30. p = n - k + 1;
  31. for (i = 1; i <= n; i++)
  32. if (f[i] == 0) {
  33. ans[p] = i;
  34. p++;
  35. }
  36. }
  37. }
  38. int main() {
  39. int s, i, m;
  40. while (cin >> n >> m) {
  41. int ii = 1;
  42. int s = 1;
  43. memset(f, 0, sizeof(f));
  44. while (s < m) {
  45. ii++;
  46. s = s * ii;
  47. }
  48. for (i = 1; i <= n - ii; i++) {
  49. f[i] = 1;
  50. ans[i] = i;
  51. }
  52. //确定n-i+1个数的情况下,第一个数是什么
  53. tmj(n - i + 1, m);
  54. //Out
  55. for (i = 1; i < n; i++)
  56. cout << ans[i] << ' ';
  57. cout << ans[n] << endl;
  58. }
  59. return 0;
  60. }

发表评论

表情:
评论列表 (有 0 条评论,222人围观)

还没有评论,来说两句吧...

相关阅读