10 排序次数

排序次数

时间限制:1秒        内存限制:128M

题目描述

小可学习了冒泡排序之后有很多自己的想法。经过了数个日夜的思考,小可创造了一种排序策略:

对于一个长度为n(保证是奇数)的下标从1开始的数组a,定义了一个函数:

函数f(x),如果a[x+1]<a[x],那么交换这两个元素。

然后,小可定义i=1,进行如下操作,每次操作结束后ii都会加一:

如果ii是奇数,执行函数f(1),f(3),..,f(n-2),否则执行函数f(2),f(4),..,f(n-1)

小可想知道进行多少次操作后序列变为升序排列。

输入描述

第一行一个正整数t(1≤t≤100),代表有t组输入。

对于每组输入,第一行一个正整数n(3≤n≤999),并且n是奇数,代表数组的长度。

第二行n个不同的数a[1],a[2],..,a[n]​​(1≤a​[i]​​≤n)代表一个数组。

输出描述

对于每组输入,输出给定的数组进行多少次操作后数组变为升序排列。

样例输入

3
3
3 2 1
7
4 5 7 1 3 2 6
5
1 2 3 4 5

样例输出

3
5
0

提示

一次操作指的是执行一次f(1),f(3),..,f(n-2)或f(2),f(4),..,f(n-1),而不是执行了多少次函数f(x)

tips:个别变量名会有改变,用ans替代题干中的i

这题其实非常简单,直接模拟就行了

BUT!!!

有个关键点需要注意

题目中说定义i为1

但提示中说输出的是执行一次f(1),f(3),..,f(n-2)或f(2),f(4),..,f(n-1)

所以我们输出时要减一

所以我们就要:

cout<<ans-1<<endl;

(多组测试数据,所以才换行)

这题还有个优化:

如果这个数组本身就有序,那么我们就不需要执行f(x)函数了

所以判断代码如下:

if(che()) cout<<"0"<<endl;

(che函数为判断数组是否有序)

我们会发现执行f(x)函数只有在a数组无序时才执行

然而ans的值不只是1

所以普通的if判断是不可以滴

所以我们就需要用到循环判断——while(表达式)的方法来判断a数组是否有序

代码如下:

while(!che()){
               if(ans%2!=0){
                   for(int i=1;i<=n-2;i+=2){
                       f(i);
                   }
                   ans++;
            }else{
                for(int i=2;i<n;i+=2){
                    f(i);
                }
                ans++;
                } 
            }

输入、定义、f(x)函数,che()函数想必大家懂得都懂

所以——

你们最爱的AC代码来了:

#include<bits/stdc++.h>
using namespace std;
int n,ans=1,a[1000],t,b[1005];
bool che(){
    for(int i=1;i<=n;i++){
        if(a[i]!=b[i]) return 0;
    }
    return 1;
}
void f(int x){
    if(a[x+1]<a[x]) swap(a[x+1],a[x]);
}
int main(){
    cin>>t;
    while(t--){
        cin>>n;
        ans=1;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            b[i]=a[i];
        }
        sort(b+1,b+n+1);
        if(che()) cout<<"0"<<endl;
        else{
            while(!che()){
               if(ans%2!=0){
                   for(int i=1;i<=n-2;i+=2){
                       f(i);
                   }
                   ans++;
            }else{
                for(int i=2;i<n;i+=2){
                    f(i);
                }
                ans++;
                } 
            }
            cout<<ans-1<<endl;
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值