1 条题解
-
0
自动搬运
来自洛谷,原作者为

Meepo
**搬运于
2025-08-24 21:59:30,当前版本为作者最后更新于2018-09-17 22:01:23,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
推荐我的博客
sorted = false while (not sorted): sorted = true moo for i = 0 to N-2: if A[i+1] < A[i]: swap A[i], A[i+1] for i = N-2 downto 0: if A[i+1] < A[i]: swap A[i], A[i+1] for i = 0 to N-2: if A[i+1] < A[i]: sorted = false问上述程序会输出几次moo。
首先读题,知道他想让你做什么。
奶牛的代码就是问你如果把冒泡排序该成双向的要排几次。
如果普通的冒泡,那么他的遍数= max {1,每个数前面有几个比它大};
因为你每次会把一个比某个数小的数移到这个数后面。
我们先离散化,每个数的值为他的排名,就是第几大。
例如 100 1000 10000离散化后是1 2 3;
同理我们可以得到双向冒泡排序遍数=max{前?个位置上值>?的数有多少个,1}
注意它和普通冒泡排序的不同。
为什么结论是这个?
因为对于每个?
- 向后扫会保证把前 ? 个位置上一个值> ? 的数扔到后边去
- 向前扫会保证被换到前? 个位置上的新数的值是≤ ? 的
如果不懂可以看下面。
拿样例举例
5
1 8 5 3 2
离散化后 1 5 4 3 2
位置为 1 2 3 4 5
例如i=3
前3个数分别是1 5 4
5和4>3
后两个数分别是 3 2
3 2<=3
所以我们就换了两次。
然后我们就可以模拟了。
懒得模拟写树状数组也行。
#include <cstdio> #include <algorithm> using namespace std; const int N=100005; struct data { int val,num; friend bool operator <(data x,data y){if(x.val==y.val)return x.num<y.num;return x.val<y.val;} }a[N]; int n,ans=1,cnt; int vis[N]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i].val),a[i].num=i; sort(a+1,a+n+1); for(int i=1;i<=n;i++) { if(i<a[i].num) cnt++; if(vis[i]) cnt--; vis[a[i].num]=true; ans=max(ans,cnt); } printf("%d",ans); }
- 1
信息
- ID
- 3354
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者