【刷题第三天】归并排序——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 }

浙公网安备 33010602011771号