NO.20十六届蓝桥杯模拟赛第三期下

8

小蓝种了一块玉米地,玉米地长n米,宽m米,每平方米产玉米a千克。请问小蓝的玉米地一共能产多少千克玉米
【输入格式】
输入三行。第一行包含一个正整数 n ,第二行包含一个正整数 m ,第三行包含一个正整数 a 。
【输出格式】
输出一行,包含一个整数,表示答案。


#include 
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m, a;
    cin >> n >> m >> a;
    cout << n * m * a << '\n';

    return 0;

9

小蓝有一个数组 a[1], a[2], …, a[n], 一个“再创新高”的位置是指一个位置 p ,a[p] 的值比之前每个位置的值都大。
请求出小蓝的数组中有多少个再创新高的位置。
【输入格式】
输入的第一行包含一个整数 n 。
第二行包含 n 个整数,相邻数之间使用一个空格分隔,依次表示 a[1], a[2], …, a[n]
【输出格式】
输出一行,包含一个整数,表示答案。


#include 
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

	//定义一个整数变量n,用于存储数组的长度
    int n;
    //从标准输入读取一个整数,赋值给n
    cin >> n;
    //创建一个长度为n的整数类型的向量a,用于存储输入的整数
    vector a(n);
    //使用范围for循环遍历向量a中的每个元素,&x表示使用引用,这样可以直接修改向量中的元素
    for (auto &x : a) {
	    //从标准输入读取一个整数,赋值给向量a中的当前元素
        cin >> x;
    }

	//定义两个整数变量,ans用于记录满足“当前元素大于之前所有元素”的元素个数,初始值为0;mx用于记录当前遍历过的元素中的最大值,初始值为-1
    int ans = 0, mx = -1;
    //使用范围for循环遍历向量a中的每个元素
    for (auto x : a) {
	    //如果当前元素x大于之前遍历过的元素中的最大值mx,则说明当前元素满足条件
        if (x > mx) {
            //满足条件时,将计数器ans加1
            ans += 1;
            //更新最大值mx为当前元素x
            mx = x;
        }
    }

	//将满足条件的元素个数ans输出到标准输出,并换行
    cout << ans << '\n';

    return 0;
}

10

给定四个字符串 a, b, c, d,请将这四个字符串按照任意顺序依次连接拼成一个字符串。
请问拼成的字符串字典序最小是多少?
【输入格式】
输入四行,每行包含一个字符串。
【输出格式】
输出一行包含一个字符串,表示答案。


#include 
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

	//创建一个包含4个字符串的向量strs,用于存储输入的4个字符串
    vector strs(4);
    //定义一个字符串ans,用于存储最终结果,初始为空
    string ans;
    //使用范围for循环遍历向量strs中的每个字符串,&s表示使用引用,这样可以直接修改向量中的字符串
    for (auto &s : strs) {
	    //从标准输入读取一个字符串,赋值给向量strs中的当前元素
        cin >> s;
        //将读取的字符串拼接起来,作为初始的结果字符串
        ans += s;
    }

	//创建一个包含4个整数的向量p,用于存储字符串的排列索引
    vector p(4);
    //使用iota函数将向量p初始化为{0, 1, 2, 3},表示字符串的初始排列顺序
    iota(p.begin(), p.end(), 0);

	//使用next_permutation函数生成向量p的所有排列,直到无法生成下一个排列为止。
    do {
	    //定义一个临时字符串temp,用于存储当前排列所形成的新字符串
        string temp;
        //使用范围for循环遍历向量p中的每个索引
        for (auto x : p) {
	        //根据索引x从向量strs中取出对应的字符串,并拼接成新的字符串temp
            temp += strs[x];
        }
        //如果当前排列所形成的新字符串temp的字典序小于当前的结果字符串ans,则更新ans为temp
        if (temp < ans) {
            ans = temp;
        }
    } while (next_permutation(p.begin(), p.end()));

    cout << ans << '\n';

    return 0;
}

iota 函数是 C++ 标准库  头文件中提供的一个实用函数,其主要作用是将一个连续递增的序列填充到指定的容器或数组中

template< class ForwardIt, class T >
void iota( ForwardIt first, ForwardIt last, T value );
  • first:这是一个前向迭代器(Forward Iterator),它指向要填充序列的容器或数组的起始位置。
  • last:同样是一个前向迭代器,指向要填充序列的容器或数组的结束位置(不包含该位置的元素)。
  • value:填充序列的起始值,后续元素的值会依次递增。

next_permutation 是 C++ 标准库  头文件中提供的一个非常实用的函数,用于生成序列的下一个排列。

// 版本 1:使用元素类型的 operator< 进行比较
template< class BidirIt >
bool next_permutation( BidirIt first, BidirIt last );

// 版本 2:使用自定义的比较函数 comp 进行比较
template< class BidirIt, class Compare >
bool next_permutation( BidirIt first, BidirIt last, Compare comp );
  • first:双向迭代器(Bidirectional Iterator),指向序列的起始位置。

  • last:双向迭代器,指向序列的结束位置(不包含该位置的元素)。

  • comp:自定义的比较函数,用于定义元素之间的顺序关系。它接受两个元素作为参数,并返回一个布尔值,表示第一个元素是否应该排在第二个元素之前。

  • 如果序列存在下一个排列,函数会将序列转换为下一个排列,并返回 true

  • 如果序列已经是最后一个排列(即元素按降序排列),函数会将序列重置为第一个排列(即元素按升序排列),并返回 false

11

蓝桥村正在给村民们发放礼物。礼物通过一个礼物发放机完成。
村民们在机器前排着队领取礼物。
每个礼物有一个价值 v[i] ,有的高,有的低。每位村民有自己对于礼物的期望值 e[i]
礼物发放机每次会显示一个礼物,如果礼物的价值大于等于村民的期望值,村民就会高兴地把礼物拿走,并离开礼物发放机。如果礼物的价值比村民的期望值低,村民会让这个礼物取消,并让礼物发放机显示下一个礼物,并重新检查是否满足期望。村民会重复让礼物发放机显示下⼀个礼物,直到礼物发放机没有更多可以显示的礼物或礼物的价值大于等于自己的期望值。
如果礼物发放机中的所有礼物都显示完了,那么还没领到礼物的村民就无法领取礼物了。
如果所有的村民都领到了礼物,而礼物发放机还有礼物显示,村民们也不会再领取礼物。
现在,小蓝知道了每位村民的期望值,也知道了礼物发放机上礼物的显示顺序,请问总共有多少村民拿到了礼物?
【输入格式】
输入的第一行包含一个整数 n ,表示村民的个数。
第二行包含 n 个整数,相邻数之间使用一个空格分隔,依次表示排队的每位村民的期望值 e[i]
第三行包含一个整数 m ,表示礼物发放机会显示的礼物个数。
第四行包含 m 个整数,相邻数之间使用一个空格分隔,依次表示礼物发放机显示的礼物的价值 v[i]
【输出格式】
输出一行,包含一个整数,表示答案。


#include 
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

	//定义两个整数变量n和m,分别用于存储序列e和v的长度
    int n, m;
    //从标准输入读取一个整数,赋值给n,表示序列e的长度
    cin >> n;
    //创建一个长度为n的整数向量e,用于存储序列e的元素
    vector e(n);
    //使用范围for循环遍历向量e中的每个元素,&x表示使用引用,这样可以直接修改向量中的元素
    for (auto &x : e) {
	    //从标准输入读取一个整数,赋值给向量e中的当前元素
        cin >> x;
    }
    //从标准输入读取一个整数,赋值给m,表示序列v的长度
    cin >> m;
    //创建一个长度为m的整数向量v,用于存储序列v的元素
    vector v(m);
    //使用范围for循环遍历向量v中的每个元素,&x表示使用引用,这样可以直接修改向量中的元素
    for (auto &x : v) {
	    //从标准输入读取一个整数,赋值给向量v中的当前元素
        cin >> x;
    }

	//定义一个整数变量ans,用于记录匹配的数量,初始值为0
    int ans = 0;
    //使用双指针i和j分别遍历序列e和v。i从0开始遍历序列e,j从0开始遍历序列v
    for (int i = 0, j = 0; i < n && j < m; i++) {
	    //当j没有超出序列v的范围且e[i]大于v[j]时,不断将j指针向后移动,跳过那些小于e[i]的元素
        while (j < m && e[i] > v[j]) {
            j += 1;
        }
        //如果j已经超出了序列v的范围,说明序列v中没有合适的元素可以与e[i]匹配,此时跳出循环
        if (j == m) {
            break;
        }
        //如果找到了合适的匹配元素,将匹配数量ans加1
        ans += 1;
        //将j指针向后移动一位,以便继续匹配下一个元素
        j += 1;
    }

    cout << ans << '\n';

    return 0;
}

12

小蓝有一个 n 行 m 列的矩阵 a[i][j],他想着矩阵中找出一个“十”字形状的区域,使得区域内的值的和最大。
一个“十”字形状的区域可以由两个行号r1、r2和两个列号c1、c2表示。“十”字的区域内包括第r1行到r2行的所有元素,以及第c1列到c列的所有元素,既不在这几行也不在这几列的元素不在区域内。
为了保证是一个“十”字的形状,必须满足 1 < r1 <= r2 < n , 1 < c1 <= c2 < m。
【输入格式】
输入的第一行包含两个整数n, m,分别表示行数和列数。
接下来n行,每行包含m整数,相邻数之间使用一个空格分隔,依次表示矩阵的每行每列的值,本部分的第i行第j列表示 a[i][j]
【输出格式】
输出一行包含一个整数,表示最大的和。

5 6 
1 -1 2 -2 3 -3 
-1 2 -2 3 -3 4 
2 -2 3 -3 4 -4 
-2 3 -3 4 -4 5 
3 -3 4 -4 5 -5

14


#include 
using namespace std;

//定义一个常量inf表示无穷大,用于初始化一些变量,这里用1e9近似表示无穷大
constexpr int inf = 1e9;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

	//定义两个整数变量n和m,分别表示二维数组的行数和列数
    int n, m;
    //从标准输入读取n和m的值
    cin >> n >> m;
    //创建一个n行m列的二维向量a,用于存储输入的数组元素
    vector> a(n, vector(m));

	//从标准输入读取每个元素的值,并存储到a中
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> a[i][j];
        }
    }

	//创建四个n行m列的二维向量L、R、U、D,分别用于存储从左到右、从右到左、从上到下、从下到上的最大连续和
    vector> L(n, vector(m)), R(n, vector(m)), U(n, vector(m)), D(n, vector(m));

    // 预处理: s = max(s, 0) + w
    //外层循环用于遍历二维数组a的每一行,i表示当前正在处理的行号,范围从0到n - 1,其中n是二维数组a的行数
    for (int i = 0; i < n; i++) {
	    //在处理每一行之前,将变量s初始化为-inf(负无穷大)。用于确保初始的最大连续和不会影响后续的计算
        int s = -inf;
        //内层循环用于遍历当前行的每一列,j表示当前正在处理的列号,范围从0到m - 1,其中m是二维数组a的列数
        for (int j = 0; j < m; j++) {
	        //max(s,0)的作用是判断当前的连续和s是否为负数。如果s是负数,说明之前的连续和对当前的计算没有正向贡献,将其重置为0;如果s是非负数,则保持不变
	        //将重置后的连续和加上当前元素a[i][j],得到新的连续和
            s = max(s, 0) + a[i][j];
            //将计算得到的当前位置的最大连续和s存储到二维数组L的对应位置L[i][j]中
            L[i][j] = s;
        }
    }

    for (int i = 0; i < n; i++) {
        int s = -inf;
        for (int j = m - 1; j >= 0; j--) {
            s = max(s, 0) + a[i][j];
            R[i][j] = s;
        }
    }


    for (int i = 0; i < m; i++) {
        int s = -inf;
        for (int j = 0; j < n; j++) {
            s = max(s, 0) + a[j][i];
            U[j][i] = s;
        }
    }

    for (int i = 0; i < m; i++) {
        int s = -inf;
        for (int j = n - 1; j >= 0; j--) {
            s = max(s, 0) + a[j][i];
            D[j][i] = s;
        }
    }

    // 枚举十字中心点
    //初始化结果变量ans为负无穷大
    int ans = -inf;

	//嵌套的for循环遍历二维数组的每个元素,将其作为十字中心点
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
	        //计算以(i, j)为中心的十字区域的和,由于中心点a[i][j]在四个方向的和中都被计算了一次,所以要减去3倍的a[i][j]
            ans = max(ans, L[i][j] + R[i][j] + U[i][j] + D[i][j] - 3 * a[i][j]);
        }
    }

    cout << ans << '\n';

    return 0;
}

vector> a(n, vector(m)); 是 C++ 中用于创建二维向量(也可以理解为二维数组)的语句
vector>:这是二维向量的类型声明。外层 vector 存储的元素类型是内层 vector,即每个元素都是一个一维的整数向量
a:二维向量的名称,你可以使用这个名称来访问和操作这个二维向量
(n, vector(m)):这是构造函数的参数,用于初始化二维向量
n:表示外层向量的大小,也就是二维数组的行数
vector(m):这是一个临时的一维向量,它的大小为 m,用于初始化外层向量的每个元素。也就是说,外层向量的每个元素都是一个包含 m 个整数的一维向量,这就构成了一个 n 行 m 列的二维数组。

你可能感兴趣的:(蓝桥杯备考,蓝桥杯,职场和发展)