CSU 1674 K swap operation
2015-08-12 17:07
357 查看
Problem E: K swap operation
Time Limit: 1 Sec Memory Limit:128 MB
Submit: 3 Solved: 0
[Submit][Status][Web
Board]
Description
最近Mr.Q想要只通过一种操作来对序列进行升序排序,该操作是“交换相邻的两个数”,聪明的Mr.Q总是会选择最优的方法进行操作,也就是说他使用的交换次数是最少的。比如对于对于序列:2 3 1 4
Mr.Q会使用2次交换操作。
而对于序列:
4 3 2 1
Mr.Q会使用6次交换操作。
请你构造一个1~N的排列,使Mr.Q刚好使用 K 次操作将它按升序完成排序。
Input
第一行一个整数T(T≤50),表示数据组数。接下来每组输入数据占一行,包含一个非负整数K(0≤K≤10^9),含义如题中描述。
Output
对于每组数据你应该输出2行,假如存在多组方案,输出任意一种即可。第一行一个整数N(1≤N≤10^5),表示你构造的排列长度。
第二行输出你构造的排列,相邻两个数之间用一个空格隔开,请确保每个数都在你构造的排列中只出现1次,并且都处于范围[1,N]内。
请不要输出多余的空格或数字,否则有可能会WA的。
Sample Input
2 0 6
Sample Output
3 1 2 3 4 4 3 2 1
HINT
和那道求逆序对数的题完全相反,已知逆序对数,求序列。由前面那道题可以得出一个结论,对一个n长的倒序序列,如n=4: 4 3 2 1.
其逆序数为 3+2+1;
即n*(n-1)/2;
所以可以这样构造一个序列。
对于每一个k,都存在一个最近的为整数的n长倒序序列。
则此n对应的n*(n-1)/2逆序数和k的差就是在原倒序序列的基础上需要正交换的次数。
#include <stdio.h> #include <math.h> #include <algorithm> #define N 100005 using namespace std; int n; long long k; int a ; int main() { int t; scanf("%d",&t); while(t--) { scanf("%lld",&k); if(k==0) { printf("3\n"); printf("1 2 3\n"); } else { n=(1+sqrt(1+8*k))/2; int k1=n*(n-1)/2; if(k1==k) { printf("%d\n",n); for(int i=0;i<n;i++) { a[i]=n-i; } } else { n++; k1=n*(n-1)/2; printf("%d\n",n); int d=k1-k; for(int i=0;i<n;i++) { a[i]=n-i; } for(int i=1;i<=d;i++) { swap(a[i],a[i-1]); } } printf("%d",a[0]); for(int i=1;i<n;i++) printf(" %d",a[i]); printf("\n"); } } }
相关文章推荐
- Linux Socket编程(不限Linux)
- select(poll)系统调用实现解析(一)
- dlopen dlerror dlclose dlsym 未定义的引用的解决方案
- RESTful架构
- Package * is missing dependencies for the following libraries: libpthread.so.0
- linux学习笔记----目录处理命令----rmdir
- ubnutu 环境下 在APACHE服务器上的访问方式上去除index.php
- 内存管理、copy、深浅拷贝
- Linux的单用户模式
- linux 下查看某个端口是否被占用
- NOI Linux Terminal(终端)使用方法(笑)
- 反向代理服务器的工作原理 (转)
- hdu 3853 LOOPS(概率DP)
- 在线聊天室的实现(4)--分布式聊天室的基础架构
- 由于csdn网站太,所以以后开始写笔记了。
- Linux 基础知识
- linux基础教程-----目录文件操作(2)
- linux驱动开发学习--对中断和内核定时器的学习笔记
- 使用Apache Solr对数据库建立索引(包括处理CLOB、CLOB)
- OpenCV学习之路