各互联网名企面试题汇总(1)

1.PPTV2015研发工程师笔试题(对称子字符串)

  输出字符串中对称的子字符串的最大长度

输入描述:测试输入包含1个测试用例,一个字符串str。

输出描述:输出最长的对称子字符串长度。

输入例子:roorle

输出例子:4

解法:中心扩展法。我们可以枚举中心位置,然后再在该位置上扩展,记录并更新得到的最长对称子串长度。

参考代码:

#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
char str1[10003];

int main()
{
    int LongestPalindrome(char *s, int n);
    while (gets_s(str1))
    {
        int n = strlen(str1);
        cout << "最大对称子串的长度为:" << LongestPalindrome(str1, n) << endl;
    }
    return 0;
}

int LongestPalindrome(char *s, int n)
{
    int i, j, max, c;
    if (s == 0 || n < 1)
    {
        return 0;
    }
    max = 0;
    //i为对称中心位置
    for (i = 0; i < n; ++i)
    {
        //对称长度为奇数
        for (j = 0; (i - j >= 0) && (i + j < n); ++j)
        {
            //判断条件的意思是i-j>=0表示头部未溢出
            //i+j<n表示尾部未溢出
            if (s[i - j] != s[i + j])
            {
                break;
            }
            c = j * 2 + 1;//更新对称长度
        }
        if (c > max)
        {
            max = c;//更新最大对称长度
        }
        //对称长度为偶数
        for (j = 0; (i - j >= 0) && (i + j + 1 < n); ++j)
        {
            //判断条件的意思是i-j>=0表示头部未溢出
            //i+j+1<n表示尾部未溢出
            if (s[i - j] != s[i + j + 1])
            {
                break;
            }
            c = j * 2 + 2;//更新对称长度
        }
        if (c > max)
        {
            max = c;//更新最大对称长度
        }
    }
    return max;
}

输出结果测试:

2.迅雷2016研发工程师笔试题(循环队列)

假设以数组A[60]存放循环队列元素,其头指针是front=47,当前队列有50个元素,则队列的尾指针的值为(B)

A。3       B。37       C。97       D。50

解释:可以把循环队列理解为钟表,一圈是60,现在头在47,所以尾部应该在47-(60-50)=37 所以选B。

3.滴滴出行2017秋招编程题(末尾0的个数)

 输入一个正整数n,求n阶乘末尾有多少个0?

输入描述:输入为一行,n(1<n<100)

输出描述:输出一个整数,即题目所求。

输入例子:10

输出例子:2

解释:N!能产生0的质数组合只能是2 *   5,也就是说当对N!进行质数分解之后,N!末尾0的个位M取决于2的个数X和5的个数Y的最小值,即M =  min(X,Y)。又因为能被2整除的数出现的频率比能被5整除的数高得多,且出现一个5的时,最少会同时出现一个2,所以M =  Y。即得出Y的值就可以得到N!末尾0的个数。

完整代码如下:

#include<iostream>
using namespace std;
static long GetZerosNum(long n);
int main()
{
    long n;
    
    printf("请输入一个正整数n:\n");
    scanf_s("%d",&n);
    //printf("\n");
    printf("%d!末尾0的个数为:%d\n", n, GetZerosNum(n));
    return 0;
}
//统计n!末尾0的个数
static long GetZerosNum(long n)
{
    long num = 0;
    int i, j;
    for (i = 1; i <= n; i++)
    {
        j = i;
        while (j % 5 == 0)
        {
            num++;
            j /= 5;
        }
    }
    return num;
}

测试结果:

 4.美团2016研发工程师笔试题(求平均年龄)

题目要求:已知某公司总人数为w,平均年龄为y(每年三月末计算,同时每年三月初入职新人),假设每年离职率为x(0<x<1),每年保持所有员工总数不变进行招聘,新员工平均年龄21岁。从今年三月末开始,请实现一个算法,可以计算出第N年后公司员工的平均年龄(结果向上取整)

解释:感觉这道题没有什么难度,但是存在一个坑点,有可能就容易忽视掉这个问题,每过一年年龄就会加1。

完整代码如下:

#include<iostream>

using namespace std;

int main()
{
    int w, n;//w为公司总人数,n为n年后
    float x, y;//x为离职率(0<x<1),y为起始平均年龄
    int GetAverageAge(int w, float y, float x, int n);
    printf("依次键入:总人数w、初始平均年龄y、离职率x、经过n年\n");
    cin >> w >> y >> x >> n;
    printf("%d年后公司平均年龄为%d\n", n, GetAverageAge(w, y, x, n));
    return 0;
}

int GetAverageAge(int w, float y, float x, int n)
{
    int i;
    int AverageAge;
    for (i = 0; i <= n; i++)
    {
        ++y;
        y = (1 - x)*w*y + 21 * x*w;
        y /= w;
    }
    AverageAge = ceil(y);
    return AverageAge;
}

测试结果为:

 5.阿里巴巴2015研发工程师笔试题(进制转换)

题目:用十进制计算30!,将结果转换为3进制表示的话,该进制下的结果末尾会有(E)个0

A. 6       B. 8     C. 10     D. 12      E. 14     F. 16

解释:选E,这个问题可以转化为:30!中最多可以被多少个3整除,即0~30中3的倍数个数+9的倍数个数+27的倍数个数

(30%3==0)个数为10,(30%9==0)个数为3,(30%27==0)个数为1。10+3+1=14,选E。

6.360校招笔试2016(直接插入排序)

设有一组初始化关键字序列为{30、20、10、25、15、28},则第4趟直接插入排序结束后的结果是(B)

A。 10、15、20、25、28、30

B、 10、15、20、25、30、28

C、 10、20、30、25、15、28

D、 10、20、25、30、15、28

解释:

直接插入排序的基本思想:第i趟排序将序列中的第i+1个元素ki+1插入到一个已经按值有序的子序列(k1,k2,。。。,ki)中的合适位置,使得插入后的序列仍然保持按值有序。

初始序列:{(30),20,10,25,15,28}

第一趟::{(20,30),10,25,15,28}

第二趟::{(10,20,30),25,15,28}

第三趟::{(10,20,25,30),15,28}

第四趟::{(10,15,20,25,30),28}

第五趟::{(10,15,20,25,28,30)}

7.乐视2017暑期实习生笔试题(有序数组)

对一个含有20个元素的有序数组做二分查找,数组起始下标为1,则查找A[2]的比较序列的下标为()

A.、 9、5、4、2

B、 10、5、3、2

C、 9、6、2

D、 20、10、5、3、2

解释:二分查找即折半查找,基本思想是:减少查找序列的长度,分而治之地进行关键字的查找。

折半查找的原则是:(起始下标+末尾下标)/2,向下取整

第一次:(1+20)/2=10.5,取10

第二次:(1+10)/2=5.5,取5

第三次:(1+5)/2=3,取3

第四次:(1+3)/2=2,取2      

所以结果为:10、5、3、2 选B

8.有道云2015校招笔试(屏幕解锁方案)

题目描述:在满足以下条件的前提下,手机解锁九宫格一共有多少种解锁图案?

  条件1:解锁图案至少经过两个点

  条件2:经过的点不能重复

解法:用深度优先递归,如果当前路径大于2个点小于等于9个点并且无重复,加入到结果集,添加周围未遍历过的点继续调用递归。

完整代码如下:

 

#include<iostream>
#include<cstring>
using namespace std;
int mark[10][10];//标记非法路径的数组
int vis[10];//标记格子是否使用
int num[20], ans = 0, lim;
void dfs(int cnt)  //深度优先遍历
{
    if (cnt >= 2) 
    {
        //当点数大于等于2时,结果加1
        ans++;
    }
    for (int i = 1; i <= 9; i++)   //从1--9号格子依次遍历
    {
        if (!vis[i])//如果格子没有被使用,则进入循环
        {
            if (mark[i][num[cnt - 1]] && !vis[mark[i][num[cnt - 1]]])
                continue;
            num[cnt] = i;
            vis[i] = 1;
            dfs(cnt + 1);
            vis[i] = 0;
        }
    }
}
int main()
{
    num[0] = 0;
    memset(mark, 0, sizeof(mark));//初始化mark数组
    //标记不可能出现的路径,例如1->3->2
    mark[1][3] = 2, mark[1][7] = 4, mark[1][9] = 5;
    mark[2][8] = 5, mark[3][7] = 5, mark[3][9] = 6;
    mark[4][6] = 5, mark[7][9] = 8;
    for (int i = 1; i <= 9; i++)
        for (int j = i + 1; j <= 9; j++)
            mark[j][i] = mark[i][j]; //完成mark数组赋值
    memset(vis, 0, sizeof(vis)); //初始化vis数组
    dfs(0);
    cout << ans << endl;
    return 0;
}

测试结果为:

 

 个人能力有限,欢迎各位博友批评指正!!!

posted @ 2017-03-01 10:41  walanwalan  阅读(371)  评论(0编辑  收藏  举报