zoukankan      html  css  js  c++  java
  • 链家秋招内推编程笔试题目

    参加8.19的链家内推笔试,总体来说题目难度不大,20个选择题还有三道编程题。

    选择题,里面有两道关于IP地址计算的题目,有点忘了,不知道最后的计算有没有问题,所以还需要复习学习完的知识,

    因为不知道什么时候就会遇到相关的问题。

    编程题,自我感觉,难度是偏简单的,如果不能达到两道AC,那就是不合格了。

    1. 给定的一个1,2,3组成的数字序列,排成升序所需的最少交换次数 。

    样例输入:

    9

    2

    2

    1

    3

    3

    3

    2

    3

    1

    样例输出:
    4

    思路:

    应使用贪心算法。

    分析:先存入数组,然后记录有多少个1,多少个2,多少个3,然后记录应该是1的领地里不是1的个数,记录2的领地里3的个数,记录3的领地里2的个数 则我们要做的是把1的领地里非1的元素同后面两个区域里的1交换, 在1的领地里把2同 2的领地里的1 交换,把3同 3的领地里的1 进行交换 。 完了会出现2和3里面分别有3和2的情况,取2和3里的非自己人的最大数,同1里的为自己人数相加即为需要交换的最小次数。

    即ans=x+max(y,z);

    总结: 统计在应该是1的位置出现2的个数为a1;

              统计在应该是2的位置出现1的个数为a2;

              统计应该是1、2的位置出现3的个数为a3;

              那么最少交换次数为:a3 + (a1 > a2 ? a1: a2)

    代码如下:

     

    #include<iostream>
    #include<vector>
    #include<cmath>
    #include<cstring>
    
    using namespace std;
    
    int main(){
        int x=0,y=0,z=0;//分别存放1的位置非1的个数,2的位置3的个数和3的位置2的个数;
        int n;
        cin>>n;
        vector<int> vec;//存放要输入的序列;
        int b[3];//用于存放序列中1,2,3的个数各是多少;
        int num;
        b[0]=0;//之前用memset初始化,结果存在很大问题。
        b[1]=0;
        b[2]=0;
    
        
        for(int i=0;i<n;i++){
            cin>>num;
            vec.push_back(num);
        }
    
        for(int i=0;i<n;i++){
            b[vec[i]-1]++;
        }
    
        for(int i=0;i<b[0];i++){
            if(vec[i]!=1){
                x++;
            }
        }
        for(int i=b[0];i<b[0]+b[1];i++){
            if(vec[i]==3){
                y++;
            }
        }
        for(int i=b[0]+b[1];i<n;i++){
            if(vec[i]==2){
                z++;
            }
        }
        int res=x+max(y,z);
        cout<<res;
        system("pause");
        return 0;
    }

     

    反思:这道题目自己做的时候,思路不对,而且没有认真去思考当要求交换最少的时候,实际上是为了尽可能一次交换使得两个数字归位。

    所以,应该尝试去写一写,多试几个例子。

     

    问题:为什么这样用memset不能清零

    #include<stdio.h>
    #include<string.h>
    int main()
    {
       int i,a[100];
       memset(a,0,100);//改memset(a,0,sizeof(a));或memset(a,0,100*sizeof(int));就可以了
       for(i=0;i<100;i++)
           printf("%d ",a[i]);
       return 0;

    }

    解决:memset(a,0,100);//改memset(a,0,sizeof(a));或memset(a,0,100*sizeof(int));就可以了

    原因:void *memset(void *s, int ch, unsigned n)函数的作用:将s所指向的某一块内存中的每个字节(注意这里是每个字节,你可能用字符串习惯了)的内容全部设置为ch指定的ASCII值,memset 工具块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为指向S的指针。 

    原本定义的是整型, 占一个字节  memset(a,0,100*sizeof(int)) 这样是100个4个字节的内存

     

     

     

    2. 类似牛客上原题,奖学金;

    小v今年有n门课,每门都有考试,为了拿到奖学金,小v必须让自己的平均成绩至少为avg。每门课由平时成绩和考试成绩组成,满分为r。现在他知道每门课的平时成绩为ai ,若想让这门课的考试成绩多拿一分的话,小v要花bi 的时间复习,不复习的话当然就是0分。同时我们显然可以发现复习得再多也不会拿到超过满分的分数。为了拿到奖学金,小v至少要花多少时间复习。
    链接:https://www.nowcoder.com/questionTerminal/cee98a512ec246a2918ea8121f7612c8 来源:牛客网

     
    示例1

    输入

    5 10 9
    0 5
    9 1
    8 1
    0 1
    9 100

    输出

    43

     

    代码如下:

     

    #include <iostream>
    #include <vector>
    #include <algorithm>
     
    using namespace std;
     
    bool cmp(const pair<int, int>p1,const pair<int, int>p2){
        return p1.second<p2.second;
    }
     
    int main()
    {
        int n,r,avg;
        while(cin>>n>>r>>avg){
            vector<pair<int, int> > vec;
            int a = 0;
            int b = 0;
            for(int i=0;i<n;i++){
                cin>>a>>b;
                vec.push_back(make_pair(a,b));
            }
     
            long long target = vec.size()*avg;
            long long score_cur = 0;
            long long time = 0;
            for(int i=0; i<vec.size(); ++i){
                score_cur += vec[i].first;
            }
     
            if(score_cur >= target){
                cout<<"0"<<endl;
            }
            else{
                sort(vec.begin(),vec.end(),cmp);
                for(int i=0;i<vec.size();i++){
                    score_cur += (r - vec[i].first);
                    if(score_cur >= target){
                        score_cur -= (r - vec[i].first);
                        time += (target - score_cur)*vec[i].second;
                        cout<<time<<endl;
                        break;
                    }
                    else
                        time += (r - vec[i].first)*vec[i].second;
                }
            }
     
        }
         
        return 0;
    }

    反思:对于这道题目的求解思路没有问题,但是在实现上有问题。对于容器的熟练度不够,除了vector,set,map等之外,还应该知道pair,熟练使用,这会很方便。

     

    3. 应该是最简单的一道,数组的去重排序,用set容器非常方便;

    利用set自带特性,直接简要去重的数组依次插入即可。

     

    代码如下:

     

    #include <iostream>
    #include<set>
    using namespace std;
    int main(int argc, char *argv[])
    {
    	int n;
    	set<int> s;
    
    	cin >> n;
    	int num;
    	for (int i = 0; i<n; i++){
    		cin >> num;
    		s.insert(num);
    	}
    
    	//set<int>::iterator it;
    
    	for (auto it = s.begin(); it != s.end(); it++)
    	{
    		if (it == --s.end())
    			cout << *it << endl;
    		else
    			cout << *it << " ";
    	}
    	system("pause");
    	return 0;
    }
    

     反思:题目很简单,但是要熟练迭代器。

    总结:从这些题目,应该能看出容器的作用了。一定要熟练。

    2018.8.22

     

     

     

     

     

  • 相关阅读:
    NHibernate 过滤器(第十五篇)
    NHibernate 存储过程 第十四篇
    NHibernate 操作视图 第十三篇
    NHibernate Linq查询 扩展增强 (第九篇)
    NHibernate 之数据操作 (第五篇)
    NHibernate之一级缓存(第十篇)
    jQueryEasyUI
    linux的systemctl 命令用法 转
    linux dig命令 转
    OPTAUTH 两步验证详解
  • 原文地址:https://www.cnblogs.com/Allen-rg/p/7410872.html
Copyright © 2011-2022 走看看