CS Academy Sorting Step

题目链接https://csacademy.com/contest/archive/task/sorting-steps

题目大意:求冒泡排序的总趟数。一趟冒泡排序能够将最大的数字交换到序列尾部。详见题目描述。

解题思路:这个题最主要的一方面就是要能够观察到,每一趟之后对于位置i的数字a[i]会与其左边最大的那个值交换。那么只需要求出来每个数左边比他大的数的个数然后取其最大值再+1即可。那么如何计算左边比他大的数字的个数呢?如果写过逆序数的可能知道其实是可以使用树状数组的。由于本题数据大小为1e9,因此先离散化,之后用树状数组记录每个数字出现的次数的前缀和,这样便可以在log(N)时间内查询得到。核心代码:

 

1 for(int i = 1; i <= n; i++){
2         int u = mmp[a[i]];//离散化后的值
3         int tmp = sum(m) - sum(u);//比u大的数字出现了几个
4         ans = max(ans, tmp);
5         add(u, 1);//记录u出现了一次
6     }

 

 

另外,假如我们将数组排序,那么,排序后的下标即是该数字前小于等于它的数字的个数,那么原数组的一个数的下标减去排序后这个数字的下标就是它之前大于它的数的个数,然后取最大值即可得到相同的结果。

 

树状数组 代码:

 

 1 const int maxn = 1e6 + 5;
 2 int n, a[maxn], sa[maxn];
 3 int bit[maxn];
 4 map<int, int> mmp;
 5 int m;
 6 
 7 void add(int x, int v){
 8     while(x <= m){
 9         bit[x] += v;
10         x += x & (-x);
11     }
12 }
13 int sum(int x){
14     int ans = 0;
15     while(x > 0){
16         ans += bit[x];
17         x -= x & (-x);
18     }
19     return ans;
20 }
21 void solve(){
22     memset(bit, 0, sizeof(bit));
23     for(int i = 1; i <= n; i++) sa[i] = a[i];
24     sort(sa + 1, sa + n + 1);
25     m = 1;
26     for(int i = 1; i <= n; i++) 
27         if(mmp[sa[i]] == 0) 
28             mmp[sa[i]] = m++;
29     int ans = 0;
30     for(int i = 1; i <= n; i++){
31         int u = mmp[a[i]];
32         int tmp = sum(m) - sum(u);
33         ans = max(ans, tmp);
34         add(u, 1);
35     }
36     printf("%d\n", ans + 1);
37 }
38 int main(){
39     scanf("%d", &n);
40     for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
41     solve();
42 }

 

排序代码 :

 1 const int maxn = 1e6 + 5;
 2 int n;
 3 int a[maxn], sa[maxn];
 4 
 5 void solve(){
 6     for(int i = 0; i < n; i++) sa[i] = a[i];
 7     sort(sa, sa + n);
 8     int ans = 0;
 9     for(int i = 0; i < n; i++){
10         int u = upper_bound(sa, sa + n, a[i]) - sa - 1;
11         ans = max(i - u, ans);
12     }
13     printf("%d\n", ans + 1);
14 }
15 int main(){
16     scanf("%d", &n);
17     for(int i = 0; i < n; i++) scanf("%d", &a[i]);
18     solve();
19 }

 

 

题目:

Sorting Steps

Time limit: 1000 ms
Memory limit: 128 MB

 

One of the most famous sorting algorithms is the bubble sort. Consider the following C++ code:

1
2
3
4
5
6
7
8
9
10
11
12
 
 
 
int steps = 0;
while (true) {
++steps;
bool isSorted = true;
for (int i = 1; i < N; ++i)
if (A[i] > A[i + 1]) {
swap(A[i], A[i + 1]);
isSorted = false;
}
if (isSorted) break;
}
 
 
 
 

 

Here, we are sorting array AA of size NN, where AA is 1-indexed. You should find the value of steps at the end of the algorithm.

Standard input

The first line contains a single integer NN.

The second line contains NN integers representing the elements of AA.

Standard output

Print the answer on the first line.

Constraints and notes

  • 1 \leq N \leq 10^51N105​​ 
  • 1 \leq A_i \leq 10^91Ai​​109​​ 
InputOutputExplanation
4
1 3 4 2
3

The array at each step:

1
2
3
4
 
 
 
1 3 4 2
1 3 2 4
1 2 3 4
 
 
 
 
4
1 2 3 4
1
1
2
 
 
 
1 2 3 4
 
 
 
 
4
4 3 2 1
4
1
2
3
4
5
 
 
 
4 3 2 1
3 2 1 4
2 1 3 4
1 2 3 4
 
 
 
 
4
3 7 4 3
3
1
2
3
4
 
 
 
3 7 4 3
3 4 3 7
3 3 4 7
 
 
 
 

 

posted @ 2017-08-17 08:01  EricJeffrey  阅读(269)  评论(0编辑  收藏  举报