[USACO18OPEN]Out of Sorts S 解题报告 (排序)


2018-10-18 14:44:35


 

原题链接:

P4378 [USACO18OPEN]Out of Sorts S

题目描述

留意着农场之外的长期职业生涯的可能性,奶牛Bessie开始在不同的在线编程网站上学习算法。

她到目前为止最喜欢的算法是“冒泡排序”。这是Bessie的对长度为NN的数组AA进行排序的奶牛码实

现。

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] sorted = false

显然,奶牛码中的“moo”指令的作用只是输出“moo”。奇怪的是,Bessie看上去执着于在她的代码中

的不同位置使用这个语句。

给定一个输入数组,请预测Bessie的代码会输出多少次“moo”。

输入输出格式

输入格式:

 

输入的第一行包含N1N100,000)。接下来N行描述了A[0]A[N1],每个数都是一个范围为0

109的整数。输入数据不保证各不相同。

 

输出格式:

 

输出“moo”被输出的次数。

 

输入输出样例

输入样例#1:
5
1
5
3
8
2
输出样例#1: 
4

♦题目大意:
给定一组数,按照上述伪代码进行,问能输出多少次moo?
♦思路:
一开始想是按照伪代码进行一遍,但是发现这样肯定过不了,要不然这样这道题的意义在哪里?
于是就试着执行一下,按照给的样例:
1 5 3 8 2
1 3 5 2 8
1 3 2 5 8
1 2 3 5 8
执行结束。
不难发现,输出moo的次数就是2往前移动的次数+1,然而这也是具有普遍性的。
对于要向右移动的数字一次就能解决,而向左移动的数字要进行多次,也就是moo输出的次数。
所以,问题就变成怎么确定向左移动次数最多的次数是多少了。
一开始每个数字对应的序号是
a 1 5 3 8 2
b 1 2 3 4 5
而排好序之后就变成
a 1 2 3 5 8
b 1 5 3 2 4
那显然答案就是ans=max(b[i]-i|i=1~n)
但这样处理之后还是会有一个点过不了,那是怎么回事呢?
后来发现,我用的是sort函数排序,可能内部将两个相同的数字也交换了顺序,这样会使答案多一个。
那只要在sort里加一个条件,如果两个数字大小相同,那将序号小的排在前面。
这样就完完全全AC了!
#include<bits/stdc++.h>
using namespace std;

int n;
struct Num{int s,x;}num[100000+10];

bool cmp(Num x,Num y)
  {return (x.s<y.s)||(x.s==y.s&&x.x<y.x);}
  
int main()
  {
      scanf("%d",&n);
      for(int i=1;i<=n;i++)
        {
            scanf("%d",&num[i].s);
            num[i].x=i;
      }
    sort(num+1,num+n+1,cmp);
    int ans=0;
    for(int i=1;i<=n;i++)
      ans=max(ans,num[i].x-i);
    printf("%d",ans+1);
    return 0;
  }

 


 

转载于:https://www.cnblogs.com/gyu0327/p/9810541.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值