【刷题第十天】贪心三——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 }

 

posted @ 2020-08-09 13:41  zym112233  阅读(669)  评论(0)    收藏  举报