【刷题第十天】贪心三——C++
1324:【例6.6】整数区间
【题目描述】
请编程完成以下任务:
1.读取闭区间的个数及它们的描述;
2.找到一个含元素个数最少的集合,使得对于每一个区间,都至少有一个整数属于该集合,输出该集合的元素个数。
【输入】
首行包括区间的数目n,1≤n≤10000,接下来的n行,每行包括两个整数a,b,被一空格隔开,0≤a≤b≤10000,它们是某一个区间的开始值和结束。
【输出】
第一行集合元素的个数,对于每一个区间都至少有一个整数属于该区间,且集合所包含元素数目最少。
【输入样例】
4 3 6 2 4 0 2 4 7
【输出样例】
2
【题目分析】
其实这道题很简单,难的是题目的意思。其实就是找到最少的几个数能够包含于所有的区间。
就像例题:数字2和6这两个数,每个区间里至少包含一个数。
怎么做呢,其实很简单,先对每个区间根据末区间的大小进行排序(从小到大),然后从头开始,用上一个的末尾判断是否在下一个区间里,如果在,那么还是用上一个的末尾判断是否在下下一个区间里……,如果不在,元素数目加一,用不在的那个末尾继续判断。
比如:红色的第一个数的比较,用第一个的末尾数和第二个区间比较,在区间内,那么和第三个区间比较,不在区间内,那么就用第三个的末尾数和下面的区间继续比较,得出是2和6这两个数。(输出是个数2)

1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 5 typedef struct My { 6 int start; 7 int end; 8 }Qu; 9 int cmp(Qu a, Qu b); 10 11 int main() { 12 Qu qujian[10000]; 13 int n, a = 0, sum = 1; 14 bool f; 15 cin >> n; 16 for (int i = 0; i < n; i++) 17 { 18 cin >> qujian[i].start >> qujian[i].end; 19 } 20 sort(qujian, qujian + n, cmp); //排序 21 for (int i = 1; i < n; i++) 22 { 23 if (qujian[a].end >= qujian[i].start && qujian[a].end <= qujian[i].end) { //判断末尾数是不是在区间内 24 continue; 25 } 26 else 27 { 28 a = i; 29 sum++; 30 } 31 } 32 cout << sum; 33 return 0; 34 } 35 36 int cmp(Qu a, Qu b) { 37 return a.end < b.end; 38 }
1224:最大子矩阵
【题目描述】
已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是1×1)子矩阵。
比如,如下的矩阵
0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2
的最大子矩阵是
9 2
-4 1
-1 8
这个子矩阵的大小是15。
【输入】
输入是一个的矩阵。输入的第一行给出N(0<N≤100)。再后面的若干行中,依次(首先从左到右给出第一行的N个整数,再从左到右给出第二行的N个整数……)给出矩阵中的N2个整数,整数之间由空白字符分隔(空格或者空行)。已知矩阵中整数的范围都在[−127,127]
【输出】
输出最大子矩阵的大小。
【输入样例】
4 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2
【输出样例】
15
【思路分析】
https://blog.csdn.net/kavu1/article/details/50547401这个是讲的最详细的了,b( ̄▽ ̄)d赞,里面是M*N的矩阵,不过也差不多
1 #include <iostream> 2 using namespace std; 3 int main() { 4 int n, n1[101][101], sum[101], max = -100000, h = 0, m = 1, sum1[101]; //max一定要的最小最小,我刚开始弄成了0,结果只有90分,找了半天的错误,吐血 5 cin >> n; 6 for (int i = 0; i < n; i++) 7 { 8 for (int j = 0; j < n; j++) 9 { 10 cin >> n1[i][j]; 11 } 12 } 13 if (n == 1) { 14 cout << n1[0][0] << endl; 15 } 16 else { 17 while (m <= n) //m要几行 18 { 19 20 //h = 0; //h第几行 21 if (m == 1) { //如果m是要1行,直接赋值即可 22 for (int j = 0; j < n; j++) 23 { 24 sum[j] = n1[h][j]; 25 } 26 } 27 else { //这里是要n行 28 for (int j = 0; j < n; j++) //这个一定要有,要给之前的清零,不然后面相加的时候会加上之前的数字 29 { 30 sum[j] = 0; 31 } 32 for (int i = h; i < m + h; i++) //从h行开始到m+h-1行的数相加 33 { 34 for (int j = 0; j < n; j++) 35 { 36 sum[j] += n1[i][j]; 37 } 38 } 39 } 40 sum1[0] = sum[0]; 41 if (sum1[0] > max) { 42 max = sum1[0]; 43 } 44 for (int i = 1; i < n; i++) //进行最大字段和 45 { 46 if (sum1[i - 1] <= 0) { 47 sum1[i] = sum[i]; 48 } 49 else { 50 sum1[i] = sum1[i - 1] + sum[i]; 51 } 52 if (sum1[i] > max) { 53 max = sum1[i]; 54 } 55 } 56 if (h + m >= n) { //行数变换 57 m++; 58 h = 0; 59 } 60 else { 61 h++; 62 } 63 } 64 cout << max << endl; 65 } 66 67 return 0; 68 }

浙公网安备 33010602011771号