• 排序


     

    Description

    题目描述:
    大家知道,给出正整数n,则1到n这n个数可以构成n!种排列,把这些排列按照从小到大的顺序(字典顺序)列出,如n=3时,列出1 2 3,1 3 2,2 1 3,2 3 1,3 1 2,3 2 1六个排列。

    任务描述:
    给出某个排列,求出这个排列的下k个排列,如果遇到最后一个排列,则下1排列为第1个排列,即排列1 2 3…n。
    比如:n = 3,k=2 给出排列2 3 1,则它的下1个排列为3 1 2,下2个排列为3 2 1,因此答案为3 2 1。

    Input

    第一行是一个正整数m,表示测试数据的个数,下面是m组测试数据,每组测试数据第一行是2个正整数n( 1 <= n < 1024 )和k(1<=k<=64),第二行有n个正整数,是1,2 … n的一个排列。

    Output

    对于每组输入数据,输出一行,n个数,中间用空格隔开,表示输入排列的下k个排列。

    Sample Input

    3
    3 1
    2 3 1
    3 1
    3 2 1
    10 2	
    1 2 3 4 5 6 7 8 9 10
    

    Sample Output

    3 1 2
    1 2 3
    1 2 3 4 5 6 7 9 8 10
    

    这道题有些古怪,在提交时只能用scanf和printf,输入输出流不能用,显示runtime error,并且在做本题的时候,自己加了一步简化运算,结果一加上就显示runtime error,提交了好多遍才找出来的这个错。。。

    本题思路:在给出的序列中从右往左找出第一个部位递增的数,然后找出这个数之后的大于该数的最小的数,将其交换,然后再将找出的数的后面升序

    所用库函数sort

    下面是自己的代码,有点复杂不过是对的(用C++提交)

    #include <stdio.h>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    int main()
    {
     int x,d,i,j,a[1500],n,w;
     scanf("%d",n);
     for(w=1;w<=n;w++)
     {
      scanf("% d%d",x,d);         //scanf("%d,%d",x,d);这样写是不对的,切记!!!!!!!!!!!
            int all=1;
      for(i=0;i<x;i++)
      scanf("%d",a[i]);
      if(x==1)
      printf("%d ",a[0]);
      else
      {
       for(i=1;i<=x;i++)
        all=all*i;
       d=d%all;
       int mis,min;
       for(i=1;i<=d;i++)
       {
        int jilu=1;
        j=x-1;
        while(a[j]<a[j-1])
        {
         if(j==1)
         {
          jilu=0;
          break;
         }
         else
          j--;
        }
        if(jilu==0)//这是从右到左都是递增的                           //出错   if(jilu=0)
        {
         for(j=0;j<x;j++)
          a[j]=j+1;
        }
        else//不是递增的
        {
         mis=j-1;//找出从右往左开始第一个不是递增的数的地址                         //  出错mis=j-1
         min=j;//记录所找出的从右往左开始第一个不是递增的数后面的最大值的地址       //   出错max=j
         //j=j+1;
         while(j<x)
         { if(a[j]<a[min]&&a[j]>a[mis])
         min=j;
         j++;
         }
         int t=a[min];
         a[min]=a[mis];
         a[mis]=t;
         sort(a+mis+1,a+x);
         // for(i=0;i<x;i++)
         //cout<<a[i]<<' ';
        }
       }
       for(i=0;i<x;i++)
        printf("%d ",a[i]);
       cout<<endl;
      }
     }
     return 0;
    }

    下面是用的新的库函数,网友代码

    #include <iostream>
    #include<algorithm>    //头文件
    using namespace std;
    int a[1024];

    int main()
    {
     int n,i,t,k;//t为实验组数
     cin>>t ;
     while(t--)
     {
      cin>>n>>k;
      for(i=0;i<n;i++)
       cin>>a[i];
      
      while(k--) 
       next_permutation(a, a + n); 
      
      for(i=0;i<n-1;i++) 
       cout<<a[i]<<' ';
      cout<<a[n-1]<<endl;
     }
     return 0;
    }

    #include <iostream>
    #include<algorithm>
    using namespace std;
    int a[1024];

    int main()
    {int n,i,t,k;
    scanf ( "%d" , &t) ;

    while(t--)
    {
    scanf ( "%d %d" , &n , &k) ;

    for(i=0;i<n;i++)
    scanf ( "%d" , &a[i] ) ;

    while(k--)

    next_permutation(a, a + n);

    for(i=0;i<n-1;i++)

      printf ( "%d " , a[i] ) ;

    printf ( "%d " , a[n-1] ) ;
    }return 0;

    }

  • 相关阅读:
    052_from表单的两种请求方式
    051_ajax的两种请求方式与传递流
    050_SpringMVC配置文件解析器
    049_文件下载为什么只能使用同步请求?
    048_io流
    048_get与url的编码问题
    062_什么是http协议?什么又是三次握手?
    020_全选功能无法出现统一协调时
    064_js中function怎么才能有返回值呢?
    Kali单用户模式下重置登录口令教程
  • 原文地址:https://www.cnblogs.com/zswbky/p/5432141.html
Copyright © 2020-2023  润新知