中文链接:
洛谷P4378
题面:
数据大小:
N(1<=N<=106)
思路:
明显地,模拟tle,所以需要我们找出规律,也就是冒泡排序次数。
根据样例:
5
1 5 3 8 2
一次排序后:
1 3 5 2 8
二次排序后:
1 3 2 5 8
三次排序后:
1 2 3 5 8
可以发现,
- 一个排序之后在i位置的数,如果它在i后面的j位置,那至少需要j-i次排序(比如样例中的 2 )(每次排序只能使这个数向前移动一位)
- 如果在i的前面,那么它是第几大的数就需要几次冒泡排序(比如样例中的 5 )。
那么排序一遍,然后逐个比较,取最大的值+1输出即可。
ac代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include <vector>
#include<algorithm>
using namespace std;
typedef long long ll;
#define MAX 100005
#define INF 10000000
struct Node{
int a;
int id;
}c[MAX];
int cmp(Node a, Node b)
{
if(a.a < b.a)
{
return 1;
}
else if(a.a == b.a)
{
if(a.id < b.id)return 1;
}
return 0;
}
int n;
int d[MAX];//第几大的数
int main()
{
scanf("%d",&n);
for(int i = 0;i<n;i++)
{
scanf("%d",&c[i].a);
c[i].id = i;
d[i] = n-i;
}
sort(c,c+n,cmp);
int max = 0;
for(int i = 0;i<n;i++)
{
int temp = (c[i].id-i)>0?c[i].id-i:i-c[i].id;
d[i] = min(d[i],temp);//比较哪个(1 或 2)情况更小就能排好第i个数
if(d[i]>max)
max = d[i];
}
printf("%d",max+1);
return 0;
}