您的位置:首页 > 编程语言 > C语言/C++

从冒泡排序说起

2016-05-24 21:02 302 查看

题目描述

众所周知,冒泡排序是众多种排序中最简单的几种之一。这种排序方式是通过扫描数组多次,不断交换位置错误的相邻的两个元素来实现的。对数组的扫描在没有可以元素可以交换的情况下即会终止。
zhaoweijie12作为一名学霸,他已经学会了冒泡排序,如果他得到一个1到n的某个排列,他可以轻松的在O(n^2)的复杂度内算出对该排列进行冒泡排序需要进行多少次交换。然而zhaoweijie12不止是一名学霸,他还是即将拥有雕塑的(男)人,作为未来的战斗霸,他还在思考是否存在某个1到n的排列,使得针对该排列进行的冒泡排序中的交换次数和之前的排列在冒泡排序中必须的交换次数是相同的。当然,他清醒的认知到这个排列不一定唯一,但是基于对第一的渴望,他希望得到那个字典序最小的排列。
zhaoweijie12不知道这个问题的答案,请帮他写个程序解决

输入

输入的第一行只有一个数字T(T<=30),表示共有T组测试数据
对于每组测试数据,第一行只有一个数字n(2<=n<=2000),第二行包括了1到n的某个排列,代表zhaoweijie12得到的原排列

输出

对于每组数据,你需要输出两行。
第一行输出对原排列进行冒泡排序需要的交换次数
第二行应包括一个1到n的排列,表示zhaoweijie12需要的那个排列

样例输入

2
3
2 1 3
4
3 1 2 4

样例输出

1
1 3 2
2
1 3 4 2

#include<iostream>

#include<algorithm>

#include<cmath>

#include<cctype>

#include<cstring>

#include<fstream>

#include<iomanip>

#include<string>

using namespace std;

void f(int k,int n,int s,int a[],int b[]){

    int c[1000],x=0,y=0,z=s;

    for(int i=0;i<1000;i++) c[i]=a[i];

    for(int i=0;i<k;i++){

        int tmp=c[z];

        c[z]=c[z+1];

        c[z+1]=tmp;

        z++;

    }

    for(int i=0;i<n;i++) {

        if(c[i]==b[i]) x++;

        if(c[i]==a[i]) y++;

     }

     if(x==n||y==n) {

        s++;

        f(k,n,s,a,b);

     }

     else for(int i=0;i<1000;i++) a[i]=c[i];

}

int main()

{

    int a[1000],b[1000],k,n,m;

    int t;

    cin>>t;

    while(t--){

        while(cin>>n){

            k=m=0;

        for(int i=0;i<n;i++) {

            cin>>a[i];

            b[i]=a[i];

        }

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

        for(int j=i+1;j<n;j++)

           if(a[i]>a[j]){

                int tmp=a[i];

                a[i]=a[j];

                a[j]=tmp;

                k++;

           }

    f(k,n,m,a,b);

    cout<<k<<endl;

    for(int i=0;i<n-1;i++) cout<<a[i]<<" ";

    cout<<a[n-1]<<endl;

    }

    }

    return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ acm 冒泡排序