hdu 5122 K.Bro Sorting【思维+树状数组】

本文介绍了一种名为K.BroSorting的排序算法,该算法通过随机选择元素并与后续较小元素交换来逐步排序序列。文章提供了算法的具体实现思路及代码,并通过样例解释了算法的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

K.Bro Sorting

Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others)
Total Submission(s): 2390    Accepted Submission(s): 1114

Problem Description

Matt’s friend K.Bro is an ACMer.

Yesterday, K.Bro learnt an algorithm: Bubble sort. Bubble sort will compare each pair of adjacent items and swap them if they are in the wrong order. The process repeats until no swap is needed.

Today, K.Bro comes up with a new algorithm and names it K.Bro Sorting.

There are many rounds in K.Bro Sorting. For each round, K.Bro chooses a number, and keeps swapping it with its next number while the next number is less than it. For example, if the sequence is “1 4 3 2 5”, and K.Bro chooses “4”, he will get “1 3 2 4 5” after this round. K.Bro Sorting is similar to Bubble sort, but it’s a randomized algorithm because K.Bro will choose a random number at the beginning of each round. K.Bro wants to know that, for a given sequence, how many rounds are needed to sort this sequence in the best situation. In other words, you should answer the minimal number of rounds needed to sort the sequence into ascending order. To simplify the problem, K.Bro promises that the sequence is a permutation of 1, 2, . . . , N .

Input

The first line contains only one integer T (T ≤ 200), which indicates the number of test cases. For each test case, the first line contains an integer N (1 ≤ N ≤ 106).

The second line contains N integers ai (1 ≤ ai ≤ N ), denoting the sequence K.Bro gives you.

The sum of N in all test cases would not exceed 3 × 106.

Output

For each test case, output a single line “Case #x: y”, where x is the case number (starting from 1), y is the minimal number of rounds needed to sort the sequence.

Sample Input

2

5

5 4 3 2 1

5

5 1 2 3 4

Sample Output

Case #1: 4

Case #2: 1

Hint

In the second sample, we choose “5” so that after the first round, sequence becomes “1 2 3 4 5”, and the algorithm completes.

Source

2014ACM/ICPC亚洲区北京站-重现赛(感谢北师和上交)


题目大意:

给你N个数,每一次选择一个数,然后和其之后的数判断,就和冒泡排序一样,如果这个数大于后边那个数,那么交换即可,一直交换到不能交换为止,问最少选择几次这样的操作就能够使得整个序列是递增的。


思路:


1、一开始以为a【i】>a【i+1】output++即可,但是一组数据就能hack掉这样的思路:

4

1 3 4 2


2、正确的思路是这样的:如果当前数的后边有比他小的数存在,那么这个数就是一定要和那个数进行交换,那么当前数也就是说一定要选择上,因为数据范围比较大,要想做到这一点的统计工作直接暴力是不行的,那么我们用树状数组优化即可。


3、将输入的数据倒序之后,每添加当前数据之前,先查询一下当前数之前有没有比这个数小的,如果有output++即可,然后添加上当前数据到树里边。


Ac代码:


#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[1000400];
int tree[1000400];
int n;
int lowbit(int x)
{
    return x&(-x);
}
int sum(int x)
{
    int sum=0;
    while(x>0)
    {
        sum+=tree[x];
        x-=lowbit(x);
    }
    return sum;
}
void add(int x,int c)
{
    while(x<=n)
    {
        tree[x]+=c;
        x+=lowbit(x);
    }
}
int main()
{
    int t;
    int kase=0;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        memset(tree,0,sizeof(tree));
        int output=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        reverse(a,a+n);
        for(int i=0;i<n;i++)
        {
            int tmp=sum(a[i]);
            if(tmp>0)output++;
            add(a[i],1);
        }
        printf("Case #%d: %d\n",++kase,output);
    }
}





评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值