C++笔试强训6


一、选择题

1-5题

在这里插入图片描述
比较简单,直接化就行,不会计算的话,我们可以反着来,ABCD四个八进制数,转换一下,看看哪个是100就好了。
对于C选项,18^2+48+4=64+32+4=100。
故选C。


在这里插入图片描述
printf(格式化串,参数1,参数2…)
格式化串: printf第一个参数之后的参数要按照什么格式打印
%d->按照整形方式打印
%f->按照float类型打印

格式串有一定的规定,%之后跟上特定的字符才表示一定的格式化
如%Q就是无效的格式,只会打印Q
同理%%也是无效的,两个%只会打印后面的一个%
故%%%%会输出%%
故选A。
在这里插入图片描述


在这里插入图片描述
p先和*结合,表示p是一个指针,剩余的部分是char [16],表示这个指针指向的是一个char类型的数组,这个数组中存放了16个char类型的元素。

故选C。


在这里插入图片描述
考察的知识点就是数组int a[10],a[i]等同于*(a+i)。所以ABC都正确,
D错误,故选D。


在这里插入图片描述
这里会有个坑,就是大家肯能会把这个宏算出来之后再去代入,这样其实是不对的,要注意的是宏替换它只会进行替换,替换完之后就啥也不干了,换完之后该怎么算就怎么算。
比如这个题来说:

替换之后是x/=y+zy+z/y+zy+z
就是x/=3+23+2/3+23+2
x/=3+6+0+6+2
即x=x/17=6/17=0
故选D。

在这里插入图片描述


6-10题

在这里插入图片描述
如下图,最终是24+5=29
故选C
在这里插入图片描述


在这里插入图片描述
D,free释放一个指针内容后,并不会把该指针的值设置为NULL


在这里插入图片描述
*(a+1)+2,相当于数组第一行第二列元素的地址。
故选B。


在这里插入图片描述
在64位下
long 4
short 2
int 4
int* 8
vs中最大对齐数为8,最后是所有类型所占字节数最大的整数倍,即int* 类型大小的整数倍即8的整数倍即24
故选A。
在这里插入图片描述


在这里插入图片描述
故选D
在这里插入图片描述


二、编程题

题目一

题目链接:

不要二

在这里插入图片描述

提交代码:

#include <iostream>
#include<vector>
using namespace std;

int main() {
    int w, h;
    cin >> w >> h;
    int res = 0;
    vector<vector<int>> arr(w, vector<int>(h, 1));
    for (int i = 0; i < w; i++) {
        for (int j = 0; j < h; j++) {
            if (arr[i][j] == 1) {
                ++res;
                if (i + 2 < w) {
                    arr[i + 2][j] = 0;
                }
                if (j + 2 < h) {
                    arr[i][j + 2] = 0;
                }
            }
        }
    }
    cout << res;
}
// 64 位输出请用 printf("%lld")

运行结果:

在这里插入图片描述


题目二

题目链接:
此处的题目链接打不开了,我换了一道算法题,大家自己试试吧。

盛最多水的容器
在这里插入图片描述

算法思路
1.初步分析
题中给了张坐标图,横轴和纵轴都是从0开始的,显然是将数组下标当横轴,数组元素当纵轴。求盛水最多,就是求哪两条边围成的容积(实际上就是个面积)最大。容积v=底*两边中较小的那一条边(短板效应),设两个指针 left , right 分别指向容器的左右两个端点,此时容器的容积 :
v = (right - left) * min( height[right], height[left])
暴力求解法
这里我们最容易想到的就是把所有边都两两配对一下,都算一下容积,最后选个最大的不就好了?不多废话,那我们就直接两个for循环开搞,管它什么时间复杂度,我先做出来跑一边看看能不能过(手动狗头)。
比较简单就不多叙述了,直接上代码:

class Solution {
public:
    int maxArea(vector<int>& height) {
        int n = height.size();
        int ret = 0;
        // 两层 for 枚举出所有可能出现的情况
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                // 计算容积,找出最⼤的那⼀个
                ret = max(ret, min(height[i], height[j]) * (j - i));
            }
        }
        return ret;
    }
};

虽然能跑,但果不其然的被制裁了。
在这里插入图片描述

2.更进一步
那我们只好换一种方法了,这里我选择使用对撞指针来解决问题。这是上面暴力解法的图,是不是挺像小学或初中的排列组合题啊。以下图为例,暴力法一共算了10次,我们双指针解决的就是减少算的次数。
在这里插入图片描述
我们可以看到将1和5算过之后就没必要再算[1,8]、[1,6]、[1,2]了,因为这些不是底变小高不变,还是底变小,高也变小都会导致容积V变小,所以算出来的容积肯定没有1,5这个组合大。所以你看暴力解法是不是[1,8]、[1,6]、[1,2]、[1,5]都得算啊,一共得算四次,而我们优化后的只需要算一次,减少了三次。既然1已经比完了,那就right++,比下一个呗。
当然这里我们默认规定的是右边的比左边的大,即height[right]>height[left],结果是算一次后直接right++就行,如果是左边的比右边的大的话,即height[left]>height[right],这不是和前一种情况思路类似嘛,算一次后后面的就全不用算了,直接left–跳过这个边界,判断下一个边界就行了。
在这里插入图片描述
下面是整体思路,有了上面的铺垫应该不难理解。
为了方便叙述,我们假设「左边边界」小于「右边边界」。
如果此时我们固定一个边界,改变另一个边界,水的容积会有如下变化形式:
◦ 容器的宽度一定变小。
◦ 由于左边界较小,决定了水的高度。如果改变左边界,新的水面高度不确定,但是一定不会超过右边的柱子高度,因此容器的容积可能会增大。
◦ 如果改变右边界,无论右边界移动到哪里,新的水面的高度一定不会超过左边界,也就是不会超过现在的水面高度,但是由于容器的宽度减小,因此容器的容积一定会变小的。
由此可见,左边界和其余边界的组合情况都可以舍去。所以我们可以 left++ 跳过这个边界,继续去判断下一个左右边界。
当我们不断重复上述过程,每次都可以舍去大量不必要的枚举过程,直到 left 与 right 相遇。期间产生的所有的容积里面的最大值,就是最终答案。

C++完整代码:

class Solution {
public:
    int maxArea(vector<int>& height) {
        int left = 0, right = height.size() - 1, ret = 0;
        while (left < right) {
            int v = min(height[left], height[right]) * (right - left);
            ret = max(ret, v);
            // 移动指针
            if (height[left] < height[right])
                left++;
            else
                right--;
        }
        return ret;
    }
};

运行结果:
在这里插入图片描述
Java完整代码:

class Solution {
    public int maxArea(int[] height) {
        int left = 0, right = height.length - 1, ret = 0;
        while (left < right) {
            int v = Math.min(height[left], height[right]) * (right - left);
            ret = Math.max(ret, v);
            if (height[left] < height[right])
                left++;
            else
                right--;
        }
        return ret;
    }
}

运行结果:
在这里插入图片描述

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

争不过朝夕,又念着往昔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值