2021华为9.1秋招机试

9.1号的机试终于来了,怀着被暴击的心情,提前15分钟打开了浏览器,等待着“开始答题"。 终于到19:00了,点击”开始答题“,粗略的看了三道题,好家伙,除了最后一道题,其余题目都超长。这不是编程,这是阅读理解啊。热乎的解题思路走起。——2021.9.1华为秋招机试
由于很多题忘记标题了,所以自己取了一个

三道题

第一题 序列转发

题目大致描述

就是存在一个k个的序列,其中每个节点都是类似于一个转发器,有m个容量的转发量和n个容量的缓存区,从开始节点输入某随机的数据量作为第一个节点的接收量,在不超出所有节点转发能力和缓存能力的情况下,经过两轮转发,其中第二轮无输入,由开始节点的缓存区驱动,既第二轮转发由开始节点的缓存区驱动,求整个节点转发量最少的情况
坑点:由于故障,某些节点只能直接传送(不计入总的转发量中,相当于直接连一根线),但不存在连续2个节点故障,所以需要我们对某些节点透明化,且确保故障节点不连续。

解题大致思路

看了整个题目,首先想到的就是对节点进行分析,对节点抽象,能得到一个类如下:

class jie{
    public:
    jie(int a,int b):m(a),n(b){}
    int shou=0;//接受量
    int m,n;
    int zhuan=0,cun=0;//转发量和缓存量
    void operator+(jie& next){//二者工作
        next.shou=this->zhuan+next.cun;//接收前面一个节点的转发,注意这里包括了当前节点的缓存量,第一轮中默认为0,确保程序正确
        if(next.shou<next.m){
            next.zhuan=shou;
            next.cun=0;
        }else{
            next.zhuan=next.m;
            next.shou-=next.m;
            if(next.shou<next.n){
                next.cun=next.shou;
            }else{
                next.cun=next.n;
            }
        }
    }
};

由于是前一个节点的转发会影响后面的接受,所以我重载了+号运算符,表示两个节点之间的工作,

对第一轮转发描述

	jie start(0, 0);
    start.zhuan = shuru; //构造第一轮转发输入节点
    start + vt.at(0);    //跟首个节点进行工作
    //第一轮
    for (int i = 0; i < vt.size(); i++){
        res += vt.at(i).zhuan; //依次对转发量进行统计
    }
       

第二轮转发描述

    jie end(0,0);
    end+vt.at(0);
    for(int i=0;i<vt.size();i++){
        res+=vt.at(i).zhuan;
    }

基本上以上代码能够应付n=1,n=2的情况了,但是对于n>=3的情况,则需要对序列进行筛选,我们观察n=1,n=2的转发情况,如果一个节点的m+n远远小于前面一个节点,那么整个序列的转发量最终都是由后面一个节点控制,既谁最小,谁就是瓶颈。根据这个思路,先对序列排序,找出前面最小的几个,然后两个最小的之间不能超过2个故障节点的方法,对2个节点进行标记,若某一个节点不满足约束条件,则对该结点进行交换,然后重新判断,直到遍历完所有的结点,生成选取标记,根据标记结果统计转发量。
代码未完待续

第二题 类与继承

题目大致描述

开头扯了很多关于知识图谱的事情,但这些都不重要,重要的是后面一部分描述,说的是现实世界中,存在很多概念,比如子概念、实例概念(这不就是类的继承、实现?),然后说类似于知识图谱,我们用三元组来定义关系,比如 student subClassOf people 来代表一种子概念,表明student是people的子概念,又比如 apple instanceOf fruit 来代表一种实例概念,表明apple是fruit的实例概念。问,给出n个关系的描述,求 某个类 的所有实例名称(包括子类的实例)
坑点:1.题目要求字典序输出 2.关系的定义对大小写敏感,也就是说,存在关系错误定义的情况,题目的意思是忽略这种情况
降低难度点:1.关系不存在回路定义,也就是类不会成为类的子类 2.确保关系定义只有三元组形式

解题大致思路

整个解题思路都是围绕继承和实现展开,中心点在类的构建上,根据题意,我们知道一个类,包括了类名,实例对象集合,子类对象集合,所以可以构建一个类叫obj代表类

// 首先定义一个类
class obj{
    public:
    obj(string a,int d):name(a),id(d){}
    string name;//类名字
    int id=0;   //类id
    vector<int> shili;//直接实例
    vector<int> zilei;//子类
};

然后创建一个容器,保存所有的类

    // 存储所有概念
    vector<obj> vt;

关系的定义,和结果的保存都存在对类对象查找,所以必须构建一个容器,用来保存类对象的索引,我想到了map容器

//存储所有的索引
    map<string,int> mp;

在这里,mp和vt一一对应,确保索引的准确性。这些容器构建成功,接下来就是对三元组关系定义,进行语义分析了。拆分字符串,将类对象1 关系定义类型 类对象2拆分出来,然后处理,就能得到每个类相互关联的结构

//关系词都处理完毕
        if(type==0){//不满足任何要求,不处理
            ;
        }else{//处理三元组关系
            if(type==ZILEI){//处理子类关系
                vt.at(idx3).zilei.push_back(idx1);
            }
            if(type==SHILI){//处理子类关系
                vt.at(idx3).shili.push_back(idx1);
            }
        }

最后,根据题目要求,找出对应类,保存实例结果。由于需要按字典序输出,所以首先想到用set容器保存结果,并且还存在子类还有子类的递归情况,所以需要构造递归函数,遍历所有结果(这里可以不用栈和队列,因为该递归为不回溯的递归,所以基本上不会爆内存)

void tianjia(set<string>& res,vector<obj>& vt,int  idx){
     obj rs=vt.at(idx);
     //处理当前类的实例对象
        vector<int> shi=rs.shili;
        for(vector<int>::iterator it=shi.begin();it!=shi.end();it++){
            res.insert(vt.at(*it).name);
        }
        // 再然后取出子类对象
        vector<int> zi=rs.zilei;
        for(vector<int>::iterator it=zi.begin();it!=zi.end();it++){
            // 对于每个子类对象进行递归调用
            tianjia(res,vt,*it);
           
        }
}

最后,非常坑的一点就是,华为对输入输出很严格,最后输出结果少了一个空格,折腾我半天。

第三题 湖泊联通

题目大致描述

用一个m*n的矩阵描述一个地面情况,其中0代表湖泊,1代表陆地,2代表岩石,湖泊数量不固定,分布也不确定,如果打通一个陆地代价为1,打通一个岩石代价为2,问:最少需要多少代价能使得整个湖泊连通
坑点:这道题既不是考验dfs等遍历情况也不是考验动态规划,等走一步看一步
降低难度点:对角不算连通,也就是说湖泊联通的条件只有上下左右

解题大致思路

第一眼看到这个题,非常头疼,因为这既不像”迷宫问题",那种dfs遍历+剪枝就能解决,因为不存在唯一结果,也不像动态规划,下一步根据记录选择最优,因为最优解不止一个,目前还没有想法。
等待有缘大佬评论区更新。。

最后,经过将近半个月的时间学习,我对C++的熟练度又上升了,趁着热乎劲,还能把CCF也解决掉。

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值