一些笔试面试题

平常看书遇到的一些笔试面试题,有些是觉得自己没掌握的,代码都是自己写的,还是菜鸟级别,大家莫笑~有些是自己把代码写出来记录的,鞭策自己多写平常遇到的感触。一直往下加,知道找到工作那一天~嘿嘿~


1.写个类A,声明类A指针指向NULL,调用类A的方法会有什么后果,编译通过吗?
 
 
 因为非虚函数的地址对编译期来说“静态”的,也就是函数地址在编译期就已经确定了,实例地址对于非虚函数
 只是那个 this 指针参数。
 所以只要不访问类的实例数据就没什么问题。而虚函数的地址,
 是先到实例的地址前面去查找它的虚函数表所在的地址。
 然后从虚函数表里取出该函数所对应的元素(虚函数表是一个函数指针数组)来call的。
 (当然一个已知的类的虚函数表的内容也是编译期静态的,但不同类的虚函数表内容不同,即运行时多态的基础)
 所以实例如果为NULL,是个有特殊意义的值,是会触发运行时错误的。



2.给定一个函数rand()能产生0到n-1之间的等概率随机数,问如何产生0到m-1之间等概率的随机数?先把问题特殊化,例如原题变为给定一个函数rand5,该函数可以随机生成1-5的整数,且生成概率一样。现要求使用该函数构造函数rand7(),使函数rand7()可以随机等概率的生成1-7的整数。

 
 方法:利用rand5()函数生成1-25之间的数字,然后将其中的1-21映射成1-7,丢弃22-25。例如生成(1,1),(1,2),(1,3),则看成rand7()中的1,如果出现剩下的4种,则丢弃重新生成。
现在来看原题把rand()视为N进制的一位数产生器,那么可以使用rand()*N+rand()来产生2位的N进制数,以此类推,可以产生3位,4位,5位...的N进制数。这种按构造N进制数的方式生成的随机数,必定能保证随机概率平均。
   
   int random(int m , int n)  
    {  
        int k = rand();  
        int max = n-1;  
        while((max+1) < m)  )
        {  
            k = k*n + rand();    //每次增加一位的值每一位的值都是随机取的
            max = max*n + n-1;  //当最大值大于m之后则位数确定了。即25大于7之后退出循环
            if((max+1>=m && k >= (max+1)/m*m)
            //当k值大于m的(max+1)/m倍即如rand7中的k大于21时重新取随机数
            {
            k=0;
            max=0;
            }
        }  
        return k%m;    
    }  
 
 

3.求二叉树中距离最远的两个点。?
 int max=0;
 Node* Iroot=Null;
 
 int maxD(Node* root)
 {
    if(root->left==null &&root->right==null)
    {
    return 0;
    }
    else
    {
    if(root->left!null )
    leftD=maxD(root->left);
    
    }
    if(root->right!null )
    rightD=maxD(root->right);
    
    }
    if((leftD+rightD)>max)
        {
            max=leftD+rightD;
            Iroot=root;
        }
        return leftD>=rightH?(leftD):(rightD);
 }


4. .
 Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order。一句话,即为螺旋矩阵问题。
举个例子,给定如下的一个矩阵:
    [
         [ 1, 2, 3 ],
         [ 4, 5, 6 ],
         [ 7, 8, 9 ]
    ]
你应该返回:[1,2,3,6,9,8,7,4,5]。如下图所示,遍历顺序为螺旋状:

#include<iostream>

using namespace std;
//int a[][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 ,10,11,12,13,14,15,16};
int a[][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
//int a[][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
void print(int m,int n)
{
    int MT =0, NT = 0;   //NT,MT是旋转一圈后+1,的值
    int i = 0, j = 0;    //i,j是旋转中的值
    while ((MT <= m / 2) && (NT <= n / 2))
    {
        if (i == MT)
        {
            while (j<(n-NT-1))
            {
                cout << a[i][j++];
                
            }
        
        }
        if (j == n-NT-1)
        {
            while (i<(m-MT-1))
            {
                cout << a[i++][j];
            }
        }
        if (i ==(m- MT-1))
        {
            while (j>(NT))
            {
                cout << a[i][j--];
            }
            
        }
        if (j == (NT))
        {
            while (i>(MT+1))
            {
                cout << a[i--][j];
            
            }
        
        }
        MT++;
        NT++;
    }
    if(n%2==0)cout << a[i][j];     //当列为偶数时,一圈当中的最后一次不转


}
void main()
{
    
    print(5,3);
}


5.//华为划屏
string touchScreen(int x1, int y1, int x2, int y2)
{
    if (x1 == x2&&y1 == y2)
    {
        return "CLICK";
    }
    if (x2 >= x1)
    {
        if (x2 == x1)
        {
            if (y2 > y1)
            {
                return "down";
            }
            else
            {
                return "up";
            }
        }
        if ((y2 - y1) / (x2 - x1) >= -1 && (y2 - y1) / (x2 - x1) <= 1)
        {
            return "right";
        }
        if ((y2 - y1) / (x2 - x1) <-1)
        {
            return "up";
        }
        if ((y2 - y1) / (x2 - x1) >1)
        {
            return "down";
        }
    }
        if (x2 < x1)
        {

            if ((y2 - y1) / (x2 - x1) >= -1 && (y2 - y1) / (x2 - x1) <= 1)
            {
                return "left";
            }
            if ((y2 - y1) / (x2 - x1) <-1)
            {
                return "down";
            }
            if ((y2 - y1) / (x2 - x1) >1)
            {
                return "up";
            }

        }



    }



//华为字符压缩
void stringZip(const char *pInputStr, long lInputLen, char *pOutputStr)
{
    int num = 1;
    int outNum = 0;
    for (int i = 0; i < lInputLen; i++)
    {
        if (pInputStr[i] == pInputStr[i + 1])
        {
            ++num;
            continue;
        }
        else
        {
             if (num>9)
                        {
                            while( (num/10)>0)
                            {
                                
                                pOutputStr[outNum++] = num/10 + '0';
                                num = num % 10;
                            }
                        }
            if (num > 1&& num<10)
            {

        
                pOutputStr[outNum++] = num + '0';
                pOutputStr[outNum++] = pInputStr[i];
                num = 1;
            }

            else
            {
                pOutputStr[outNum++] = pInputStr[i];
            }
        }
    }
    pOutputStr[outNum] = '\0';
}

//华为走路有洞
string hole(int* in,int length)
{
    
    for (int i = 0; i < length-1; i=i+2)
    {
        if (in[i]>=500)
        {
            return "yes";
        }
        int meter1 = in[i] * 100 ;
        int meter2 = in[i] * 100 + in[i + 1];
        if ((meter1 % 65 + in[i + 1])>65) return "no";
    }
    return "yes";
}



//暴风影音查找最大字串
string findMax(string lIn, string rIn)
{
    int max = 0, num = 1;
    int l = lIn.size(), r = rIn.size();
    string out = "";
    for (int i = 0; i <l; i++)
    {
        for (size_t j = 0; j < r; j++)
        {
            if (lIn.at(i)==rIn.at(j))
            {
                string temp = "";
                temp = lIn[i];
                int p =i+1, q = j+1;
                while (p<l&&q<r&&lIn.at(p) == rIn.at(q))
                {
                    temp = temp+lIn[p] ;
                    p++; q++; num++;
                }
                if (num>max)
                {
                    out = temp;
                    max = num;
                    num = 1;
                }
            }
        }
    }
    return out;


}






//小米字符串的四则运算  //先将四则运算转化为后缀排序 再运算~
map<char, int> m;
int math(char *in)
{
    char c[100];
    //char* c=new char[strlen(in)+1];
    int p = 0;
    stack<pair<char,int>> fuhaos;
    int length = strlen(in);
    for (int i = 0; i < length; i++)
    {
        if (in[i]<='9'&&in[i]>='0')
        {
            c[p++]=(in[i]);

        }
        else
        {
            if (in[i]=='(')
            {
                for (map<char, int>::iterator it = m.begin(); it != m.end(); it++)
                {
                    (it->second)++;
                    (it->second)++;
                }
                continue;
            }
            if (in[i] == ')')
            {
                for (map<char, int>::iterator it = m.begin(); it != m.end(); it++)
                {
                    (it->second)--;
                    (it->second)--;
                }
                continue;
            }

            if (fuhaos.empty())
            {
                fuhaos.push(pair<char, int>(in[i], m.find(in[i])->second));
                continue;
            }
        
            if (m.find(in[i])->second >= fuhaos.top().second)
            {
                fuhaos.push(pair<char, int>(in[i], m.find(in[i])->second));
            }
            else
            {
                c[p++] = fuhaos.top().first;
                fuhaos.pop();
                fuhaos.push(pair<char, int>(in[i], m.find(in[i])->second));
            }
        }
    }
    while(!fuhaos.empty())
    {
        c[p++] = fuhaos.top().first;
        fuhaos.pop();
    }
    return 0;

}
extern "C" int _cdecl wmain(int argc, wchar_t* argv[])
{
    
    m.insert(make_pair<char, int>('+', 0));
    m.insert(make_pair<char, int>('-', 0));
    m.insert(make_pair<char, int>('*', 1));
    m.insert(make_pair<char, int>('/', 1));
    //m.insert(make_pair<char, int>('(', -1));
    //m.insert(make_pair<char, int>(')', 2));

    char* in = "1*5+(2+(3-4))";
    math(in);

}


//用位运算求除法
int fun(int a, int b)
{
    int res = 0; int lef = a;
    while (lef >= b)
    {
        int m = 1;
        while (b*m <= (lef))
        {
            m = m << 1;
        }
        res += m >> 1;
        lef -= b*(m>>1);
    }
    return res;

}



6.题目B:亲友团问题

//题目B:亲友团问题
//时间限制(普通 / Java) :6000MS / 18000MS          运行内存限制 : 65536KByte
//问题描述
//在2014“华为杯”南邮大学生团体歌唱大赛每一个轮比赛现场,众多亲友团是一道亮丽的风景,他(她)们或来助威、或来观摩、或来刺探对手情报,不同亲友团之间偶尔还起冲突。为避免安全问题,主办方在赛场会划分许多独立区域,每一个区域安置一个亲友团,现在请你根据主办方提供的比赛现场信息,预测至多需要划分出多少个独立区域。
//我们将主办方提供的比赛现场信息进行简化,从1开始按顺序给进入比赛现场的每位亲友分配一个编号,依次为1、2、...、K,K为亲友总数,为保护隐私,主办方只能告诉你M组两个不同亲友属于同一亲友团信息,这些信息有可能重复。
//问题输入
//输入包括多个测试用例,首先给出测试用例数N,接着给出N个测试用例,1≤N≤100。
//每一个测试用例包括M + 1行,首先给出两个整数K和M;再依次给出M行,每行给出两个不同正整数i和j,表示两个不同亲友i和j属于同一亲友团,i≠j,1≤i≤K,1≤j≤K,,1≤K≤10000,1≤M≤10000。
//问题输出
//输出包括多行,对于每个测试用例,输出一行,给出至多需要划分出的独立区域数量。
//样例输入
//2
//3 1
//1 2
//3 2
//1 2
//2 3
//样例输出
//2
//1
 
 #include<iostream>
#include<map>
#include<vector>
using namespace std;
//int in[][2] = { 1, 2 ,2,3};
int findPlace(const int k, const int m,int** in)
{
    vector<int> v;
    int num = 0;
    for (int i = 0; i < m; i++)
    {
        if (v.end() == find(v.begin(), v.end(), in[i][0]) && v.end() == find(v.begin(), v.end(), in[i][1]))    //如果交集里面没有+1组
        {
            num++;
            v.push_back(in[i][0]);
            v.push_back(in[i][1]);
        }
        else
        {
            v.push_back(in[i][0]);
            v.push_back(in[i][1]);
        }
    }
    for (int i = 1; i < k+1; i++)
    {
        if (v.end() == find(v.begin(), v.end(), i))
        {
            num++;
        }
    }
    return num;
}


void main()
{
    int N, K, M;
    cin >> N;
    int*** allIn = new int**[N];
    for (int i = 0; i < N; i++)
    {

        cin >> K >> M;
        allIn[i] = new int*[M];
        for (int j = 0; j < M; j++)
        {
            allIn[i][j] = new int[2];
            cin >> allIn[i][j][0] >> allIn[i][j][1];

        }
        findPlace(K, M, allIn[i]);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值