【刷题第三天】归并排序——C++

【题目描述】

给定一个序列a1,a2,…,an,如果存在i<j并且ai>aj,那么我们称之为逆序对,求逆序对的数目。

【输入】

第一行为n,表示序列长度,接下来的n行,第i+1行表示序列中的第i个数

【输出】

所有逆序对总数。

【输入样例】

4
3
2
3
2

【输出样例】

3
 1 #include <iostream>
 2 using namespace std;
 3 int a[100000], b[100000];
 4 long long sum=0;                             //如果是int,范围太小,会出错
 5 void merge(int left, int right) {
 6     if (left >= right) {
 7         return;
 8     }
 9 
10     int mid = (left + right) / 2;
11     merge(left, mid);
12     merge(mid + 1, right);
13 
14     int i = left, j = mid + 1, k = left;
15     while (i <= mid&&j <= right) {
16         if (a[i] > a[j]) {
17             b[k++] = a[j++];                    //先进行b[k]=a[j]然后在进行k=k+1;j=j+1;这个很关键
18             sum += mid + 1 - i;
19         }
20         else {
21             b[k++] = a[i++];
22         }
23     }
24     while (i <= mid)
25     {
26         b[k++] = a[i++];
27     }
28     while (j <= right)
29     {
30         b[k++] = a[j++];
31     }
32     for (int i = left; i <= right; i++)
33     {
34         a[i] = b[i];
35     }
36 }
37 int main()
38 {
39     int n;
40     cin >> n;
41     for (int i = 1; i <= n; i++)
42     {
43         cin >> a[i];
44     }
45     merge(1,n);
46     cout << sum << endl;
47     return 0;
48 }

https://blog.csdn.net/acdreamers/article/details/16849761  借鉴了这个,讲述的很好,将归并求逆序对的重点说明了。

 

【题目描述】

在一次考试中,现知道了每个学生的学号和成绩,求考第k名学生的学号和成绩。学生总数不超过200名。若成绩相同,按照录入顺序排名。

【输入】

第一行有两个整数,分别是学生的人数n(1≤n≤100),和求第k名学生的k(1≤k≤n)。
其后有n行数据,每行包括一个学号(整数)和一个成绩(浮点数),中间用一个空格分隔。

【输出】

输出第k名学生的学号和成绩,中间用空格分隔。(注:请用%g输出成绩)

【输入样例】

5 3
90788001 67.8
90788002 90.3
90788003 61
90788004 68.4
90788005 73.9

【输出样例】

90788004 68.4
 1 #include <iostream>                                     //这道题的第一反应是先排序后查询,这样效率会比较低,但是用来练习归并排序挺好
 2 #include <cstdio>                                       //这个是用到C语言的输入输出时需要的头文件
 3 using namespace std;
 4 int id[101],id_fb[101];
 5 float score[101],score_fb[101];
 6 
 7 void merge(int left,int right) {
 8     if (left >= right)
 9         return;
10 
11     int mid = (left + right) / 2;
12     merge(left, mid);
13     merge(mid + 1, right);
14 
15     int i = left, j = mid + 1, k = left;
16     while (i <= mid&&j <= right) {
17         if (score[i] < score[j]) {                            //这个非常注意!!!从小到大排的话例题也能对,就是这么被坑了,花了好长时间在研究为啥错了,下次注意,读题要准确啊啊啊啊
18             id_fb[k] = id[j];
19             score_fb[k] = score[j];
20             k++;
21             j++;
22         }
23         else
24         {
25             id_fb[k] = id[i];
26             score_fb[k] = score[i];
27             k++;
28             i++;
29         }
30     }
31     while (i <= mid) {
32         id_fb[k] = id[i];
33         score_fb[k] = score[i];
34         k++;
35         i++;
36     }
37     while (j <= right) {
38         id_fb[k] = id[j];
39         score_fb[k] = score[j];
40         k++;
41         j++;
42     }
43     for (int i = left; i <= right; i++)
44     {
45         id[i] = id_fb[i];
46         score[i] = score_fb[i];
47     }
48 }
49 
50 int main() {
51     int number, who;
52     cin >> number;
53     cin >> who;
54     for (int i = 1; i <= number; i++)
55     {
56         cin >> id[i];
57         cin >> score[i];
58     }
59     merge(1, number);
60     printf("%d %g\n",id[who],score[who]);
61     return 0;
62 }

 

 https://blog.csdn.net/weixin_33919941/article/details/85867892?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase    他的代码比我简单多了,用了sort函数,又长了一个知识点,哈哈

sort函数用法:https://www.cnblogs.com/junbaobei/p/10776066.html

 

【题目描述】

给出班里某门课程的成绩单,请你按成绩从高到低对成绩单排序输出,如果有相同分数则名字字典序小的在前。

【输入】

第一行为n (0 < n < 20),表示班里的学生数目;

接下来的n行,每行为每个学生的名字和他的成绩, 中间用单个空格隔开。名字只包含字母且长度不超过20,成绩为一个不大于100的非负整数。

【输出】

把成绩单按分数从高到低的顺序进行排序并输出,每行包含名字和分数两项,之间有一个空格。

【输入样例】

4
Kitty 80
Hanmeimei 90
Joey 92
Tim 28

【输出样例】

Joey 92
Hanmeimei 90 
Kitty 80
Tim 28
 1 #include <iostream>
 2 #include <string>                           //C++要用到string字符串时一定要加的头文件!!
 3 using namespace std;
 4 string name[20],na[20];                    
 5 int score[20],sc[20];
 6 void merge(int left,int right) {
 7     if (left >= right) {
 8         return;
 9     }
10 
11     int mid = (left + right) / 2;
12     merge(left, mid);
13     merge(mid + 1, right);
14     
15     int i = left, j = mid + 1, k = left;
16     while (i <= mid&&j <= right) {
17         if (score[i] < score[j]) {
18             na[k] = name[j];
19             sc[k] = score[j];
20             k++; j++;
21         }
22         else if (score[i] > score[j]) {
23             na[k] = name[i];
24             sc[k] = score[i];
25             k++; i++;
26         }
27         else {
28             if (name[i] > name[j]) {
29                 na[k] = name[j];
30                 sc[k] = score[j];
31                 k++; j++;
32             }
33             else {
34                 na[k] = name[i];
35                 sc[k] = score[i];
36                 k++; i++;
37             }
38         }
39     }
40     while (i <= mid) {
41         na[k] = name[i];
42         sc[k] = score[i];
43         k++; i++;
44     }
45     while (j <= right) {
46         na[k] = name[j];
47         sc[k] = score[j];
48         k++; j++;
49     }
50     for (int i = left; i <= right; i++)
51     {
52         name[i] = na[i];
53         score[i] = sc[i];
54     }
55 }
56 int main() {
57     int number;
58     cin >> number;
59     for (int i = 0; i < number; i++)
60     {
61         cin >> name[i];
62         cin >> score[i];
63     }
64     merge(0,number-1);
65     for (int i = 0; i < number; i++)
66     {
67         cout << name[i] << " " << score[i] << endl;
68     }
69     return 0;
70 }
posted @ 2020-06-16 00:12  zym112233  阅读(740)  评论(0)    收藏  举报