(题目描述略)

本题题意为求给定长度为 n 的数列的后第 m 个全排列(字典序)。

对于一个给定的数列 a[0 .. n-1],求其下一个字典序的全排列算法如下:

  1. 从右向左查询最大的下标 i (0 ≤ i ≤ n-1) 使得 a[i] < a[i+1];
  2. 从左向右查询最小的元素 a[j] (i+1 ≤ j ≤ n-1) 使得 a[i] < a[j];
  3. 交换 a[i] 和 a[j];
  4. 逆置翻转 a[i+1 .. n-1]。

算法分析:我们可以发现,第一步求出的 i 下标表示 a[i+1 .. n-1] 是一个长度为 n-i-1 的最后一个全排列,且 a[i .. n-1] 是一个长度为 n-i 的非末全排列。这样,我们可以不改变 a[0 .. i-1],而对 a[i .. n-1] 求其下一个全排列。

因为以 a[i] 为起始的全排列已经完成,所以其构造方法必然是将 a[i] 换成 a[i+1 .. n-1] 中比 a[i] 大的且最小的数,即为 a[j]。下面我们来比较 a[i] 和 a[j+1] 之间的大小关系。显然,a[i] ≠ a[j+1]。假设 a[i] < a[j+1],我们有 a[i] < a[j+1] < a[j],与条件 a[j] 为所有大于 a[i] 的数中最小的数矛盾。故 a[i] > a[j+1]。

由于 a[i+1] > a[i+2] > .. > a[j] > a[j+1] > .. > a[n-1],且 a[i] < a[j],a[i] > a[j+1],故 a[i+1] > a[i+2] > .. > a[j] > a[i] > a[j+1] > .. > a[n-1]。当交换 a[i] 和 a[j] 后,a[i+1 .. n-1] 必然严格降序排列。显然,交换 a[i] 和 a[j] 前 a[i .. n-1] 的下一个排列为交换 a[i] 和 a[j] 后以 a[i] 为起始的第一个排列。于是,将 a[i+1 .. n-1] 逆置翻转,得到原数列的下一个全排列。

特别的,当 i 不存在时,原数列即为以 n 为长度的全排列的末排列。当然,在本题中无此类情况。

代码如下:

#include"iostream"
#include"stdio.h"
using namespace std;
int number[10005];
int main()
{freopen("martian.in","r",stdin);freopen("martian.out","w",stdout);int i,j,m,n,temporary;cin>>n>>m;for(i=0;i<n;i++)scanf("%d",&number[i]);while(m--){for(i=n-2;number[i]>number[i+1];i--);j=i+1;for(int k=i+2;k<n;k++)if((number[i]<number[k])&&(number[j]>number[k]))j=k;temporary=number[i];number[i]=number[j];number[j]=temporary;for(int left=i+1,right=n-1;left<right;left++,right--)temporary=number[left],number[left]=number[right],number[right]=temporary;}for(i=0;i<n;i++)printf("%d ",number[i]);return 0;
}

对于本题,我们还可以调用库函数直接出解。next_permutation 是一个定义在 algorithm 库里的函数,功能是求一个一维整型数组的下一个全排列,原理同上,用法见下。

代码如下:

#include"algorithm"
#include"iostream"
#include"stdio.h"
using namespace std;
int a[10005];
int main()
{freopen("martian.in","r",stdin);freopen("martian.out","w",stdout);int m,n;cin>>n>>m;for(int i=0;i<n;i++)scanf("%d",&a[i]);while(m--)next_permutation(a,a+n);for(int i=0;i<n;i++)printf("%d ",a[i]);return 0;
}

时间复杂度:O(nm)

NOIP2004P4 火星人 题解相关推荐

  1. excel行列突出显示_在Excel中突出显示即将到来的日期

    excel行列突出显示 Do you use Excel to keep track of upcoming payments, or other dates? To make that list m ...

  2. 火星人(洛谷P1088题题解,C++语言描述)

    题目要求 题目链接 分析 STL有一个函数next_permutation(),直接给出下一个序列. 想自己做的话,建议学习康托展开. AC代码 #include <iostream> # ...

  3. BZOJ1014: [JSOI2008]火星人prefix

    BZOJ1014: [JSOI2008]火星人prefix Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀. 比方说,有这样一个字符串:madamimadam,我们将这 ...

  4. [JSOI2008]火星人 hash+splay

    题目描述: 现在,火星人定义了一个函数 LCQ(x, y)LCQ(x,y),表示:该字符串中第 xx 个字符开始的字串,与该字符串中第 yy 个字符开始的字串,两个字串的公共前缀的长度.比方说,LCQ ...

  5. 一些noip模拟题一句话题解

    Problem A: 序列 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 12  Solved: 9 [Submit][Status][Web Bo ...

  6. 河工计院ACM2022寒假培训题单以及超详细题解

    目录 货仓选址 校门外的树 奖学金 蛇形矩阵 找硬币 回文平方 品种邻近 平方矩阵 II 十三号星期五 阶乘 干草堆 火星人 整数集合划分 最大的和 剪绳子 分巧克力 a^b 数独检查 ISBN号码 ...

  7. 洛谷P1088.火星人【模拟/搜索/康托展开】

    洛谷P1088.火星人[模拟/搜索/康托展开] 题干 题目描述 输入格式 输出格式 输入输出样例 说明/提示 题意 思路一--模拟 分析 上代码 思路二--搜索 分析 上代码 思路三--变进制数与康托 ...

  8. 火星人-洛谷 1088

    题目描述人类终于登上了火星的土地并且见到了神秘的火星人.人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法.这种交流方法是这样的,首先,火星人把一个非常大的数字告诉人类科学家 ...

  9. 题目:洛谷1088 火星人(排列组合问题)

    题目描述: 人类终于登上了火星的土地并且见到了神秘的火星人.人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法.这种交流方法是这样的,首先,火星人把一个非常大的数字告诉人类科 ...

最新文章

  1. ITSM四大管理工具的比较
  2. 【周鸿祎:当下AI技术并不完善,存四大“冰点”】
  3. 百度地图api改变覆盖物背景实例及css颜色值简介
  4. json对象和json字符串之间的转化
  5. 使用poi写入doc文档中文档打不开_基于NodeJS和浏览器的PDF文档引擎——PDFKit
  6. C++中const迭代器 和 const_iterator的区别
  7. 基于MaxCompute+PAI的用户增长方案实践
  8. SpringBoot之AOP详解
  9. 如何卸载非linux系统分区,如何卸载Linux系统分区?卸载Linux系统分区的方法-站长资讯中心...
  10. 2021-2022元宇宙报告:化身与智造,元宇宙座标解析
  11. 马克思知识点总结(二)
  12. 20春学期《计算机应用基础》在线作业2,东大20春学期《计算机应用基础》在线平时作业2答案...
  13. 递归算法在生成树型结构中,几乎完全属于无稽的算法
  14. 一天一个小技巧(1)——CSDN编辑器中文字颜色、尺寸、类型修改
  15. 文件或目录损坏且无法读取怎么办?数据恢复用这招
  16. 2017第九届广州国际园林机械与园艺工具展会刊(参展商名录)
  17. Code For Better 谷歌开发者之声 ——Tensorflow与深度学习
  18. Linux开放80端口
  19. 小程序智能聊天机器人(二)
  20. 计算机时代的英语阅读,利用微信平台提升英语类专业学生课外阅读能力的实 践意义...

热门文章

  1. js点击小图完成大图切换
  2. java 开发设计 小游戏 英雄 怪物 武器 关键代码
  3. android异步加载视频缩略图,Android 视频缩略图的缓存机制和异步加载
  4. 小程序轮播图_厉害!对准不认识的野生菌拍个图,云大学生设计的这个小程序就能自动识别...
  5. 数据表与简单Java类映射转换
  6. 黑客术语大全及其解释
  7. Python|用turtle画笔制作奥运五环
  8. 微信支付宝支付如何盈利?盈利如何?
  9. Spring AOP 学习笔记
  10. 计算机C盘空间减少,为什么我电脑C盘的空间会自己在慢慢减小????