Counter Strike HDU 2443 逆序对数

 

题目:http://acm.hdu.edu.cn/showproblem.php?pid=2443

这个题目尝试了很多种方法都过不去,上网查了一下网友们的的思路,竟然和逆序对数有关系!!

题目大意:

有n个士兵,他们都有各自的分数,有一项任务需要完成,为了能够确保合作更默契,他们的分数要差不多,所以有一个水平控制即平均数,所选的一组士兵的平均成绩必须大于该平均数。

问一共能选出多少组士兵能够完成该项任务?

思路:

求逆序对数。归并排序可以用来求逆序对数,这个没毛病。

 

代码如下:

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 void combine_sortd_list(int* to, int* sub1, int sz1, int* sub2, int sz2);
 5 void merge_sort(int* lst, int sz);
 6 const int MAX = 1e5 + 5;
 7 int arr[MAX];
 8 long long int ans;
 9 int main()
10 {
11     int Group, N, A;
12     cin >> Group;
13     while (Group--)
14     {
15         memset(arr, 0, sizeof arr);
16         cin >> N >> A;
17         for (int j, i = N-1; i >=0; --i)
18         {
19             cin >> j;
20             arr[i] = j - A + arr[i + 1];
21         }
22         ans = 0;
23         merge_sort(arr, N + 1);             //归并求逆序数
24         cout << ans << endl;
25     }
26 }
27 void merge_sort(int* lst, int sz)
28 {
29     static int tmp[MAX];
30     if (sz <= 1)return;
31     int* l = lst;
32     int lsz = (sz + 1) / 2;
33     int* r = l + lsz;
34     int rsz = sz / 2;
35     merge_sort(l, lsz);
36     merge_sort(r, rsz);
37     combine_sortd_list(tmp, l, lsz, r, rsz);
38     for (int i = 0; i < sz; ++i)lst[i] = tmp[i];
39 }
40 void combine_sortd_list(int*to, int* sub1, int sz1, int* sub2, int sz2)
41 {
42     int i = 0, j = 0, k = 0;
43     while (i < sz1&&j < sz2)
44         if (sub1[i] <= sub2[j])to[k++] = sub1[i++];
45         else
46         {
47             ans += sz1 - i;
48             to[k++] = sub2[j++];
49         }
50     while (i < sz1)to[k++] = sub1[i++];
51     while (j < sz2)to[k++] = sub2[j++];
52 }

 

由公式推导解析题目意图:http://blog.csdn.net/scorpiocj/article/details/6227528

感谢您的阅读,生活愉快~

 

posted @ 2018-02-23 10:31  林-兮  阅读(176)  评论(0编辑  收藏  举报