排序次数
时间限制: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;
}