题目描述
输入
输出
样例输入
样例输出
源代码
方法1
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#define N 1001
using namespace std;
int n, ans, a[N];
void change(int x)
{
int l, r;
ans++;
l = r = x / 2;
r++;
if (x % 2 == 1) r++;
while (l > 0) swap(a[l--], a[r++]);
}
int main()
{
int i, k;
scanf("%d", &n);
for (i = 1; i <= n; i++) scanf("%d", &a[i]);
ans = 0;
while (n > 1)
{
k = 1;
for (i = 2; i <= n; i++)
{
if (a[k] < a[i]) k = i;
}
if (k != n)
{
if (k > 1) change(k);
change(n);
}
n--;
}
printf("%d\n", ans);
return 0;
}
方法2
#include<stdio.h>
#include<stdlib.h>
int a[1002]={0};
bool flag=true;//是否满足非从小到大排序
int dex=0;//已经排好位置的数量
int conut=0;//最大值下标
int ans=0; //翻转次数
void print(int n){
for(int i=1;i<=n;i++){
printf("%d ",a[i]);
}
printf("\n");
}
void juge(int n){
int flag1=0 ;
for(int i=1;i<=n-1;i++){
if(a[i]>a[i+1]){
flag=true;
flag1++;
}
}
if(flag1==0){
flag=false;
}
}
void turn(int n){//翻转函数
//翻转第一次
int low=1,high=conut;
if(conut!=1){//最上面和不用翻转
while(low<=high){
int temp=a[low];
a[low]=a[high];
a[high]=temp;
low++;
high--;
}
// print(n)
ans++;
}
juge(n);//判断是否从小到大有序
if(flag==false){
return ;
}
//翻转第二次
low=1,high=n-dex;
while(low<=high){
int temp=a[low];
a[low]=a[high];
a[high]=temp;
low++;
high--;
}
// print(n);
ans++;
juge(n);//判断是否从小到大有序
dex++;
}
void find(int n){//查找元素
int max=-1;
for(int i=1;i<=n-dex;i++){
if(a[i]>=max){
max=a[i];
conut=i;
}
}
if(conut==n-dex){//目前位置已经是最大位置
dex++;
find(n);
}
else
return ;
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
juge(n);//判断是否从小到大有序 防止BUG
while(flag&&dex!=n-1){
find(n);
turn(n);
}
printf("%d\n",ans);
}
关于这题
这里解释一下第一种方法
思路:先找到一个最大的数 把他移到最前面 再翻转
此时最大的数已经到了末尾 我们就不再处理他 看前面的元素
即处理子数列问题
注:我们要单独去判断 最大的数是不是就是最后一个 不然会出BUG
这里ans 和 数组 我们设立的是全局变量 因为在函数里也要用到
l 和 r 是判断数组位置的 左标和 右标 当 x%2==1时 右标要加一 (不要标记成中间的数了)