360企业安全2019暑期实习算法岗笔试


       360好像之前有一轮笔试面试,不过我没投,错过了。前几天投的,今天(2019.4.24)晚上7点笔试,共90分钟,20个选择题(60分),2道编程题(40分),记录一下笔试的心得吧。
       前段时间菜鸡博主经历了很多笔试面试(腾讯正式批、阿里、京东等),也没拿到啥offer,没有太多时间写笔试面试心得。过段时间会整理一下发出来。

选择题

       选择题我就写一些我目前还记住的吧。
       1.按行存储,计算三维数组num[i][j][k]的地址。
       2.给出如下代码,问时间复杂度的下界,博主选的O ( l o g n ) O(logn)O(logn)

while(n>1){
	if(isodd(n))
		n = n*3 + 1;
	else
		n /= 2;
}

       3.汉诺塔7个盘子,多少步数。算一下就行了,答案我忘了。
       4.一个六面骰子,一个面是1,两个面是2,三个面是3,平均掷多少次能使1、2、3各出现一次。博主选的7.3,全排列算一下就行了,没多少种情况。
       5.广义表(a,b,(c,d))的表尾是什么,博主选的(b,(c,d))。
       6.给出两个样本集X、Y,计算协方差。
       7.给出正样例和负样例,计算间隔最大的最优分离超平面。
       8.线性规划问题,在下列选项中选出不对的一项。选项大概是可行域,非空,无界啥的,具体的忘了。

编程题

第一题

题意

       有一些不同颜色的气球,他们的个数不同,我们要把这些气球放在不同的盒子里,每个盒子中的气球颜色必须相同,且每个盒子最少放两个气球,且每个盒子的气球颜色个数相同。问最少需要几个盒子。

思路

       求一下这些气球个数的最大公约数,每个盒子都放这些气球即可。以下为AC代码。

代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<string>

using namespace std;

int vis[100000+5];
int cnt[100000+5];

int _gcd(int a, int b)
{
    return b?_gcd(b,a%b):a;
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(vis,0,sizeof(vis));
        int ball_num = 0;
        int max_ball = -1;
        for(int i=1;i<=n;++i)
        {
            int tmp;
            scanf("%d",&tmp);
            if(vis[tmp] == 0)
                ball_num ++ ;

            vis[tmp]++;
            max_ball = max(max_ball, tmp);
        }
        memset(cnt,0,sizeof(cnt));
        int ii = 0;
        for(int i=1;i<=max_ball;++i)
        {
            if(vis[i] != 0)
            {
                cnt[ii] = vis[i];
                ii++;
            }
        }
        sort(cnt, cnt+ball_num);

        if(ball_num == 1)
            printf("1\n");
        else
        {
            int tmp = cnt[0];
            for(int i=1;i<ball_num;++i)
            {
                int a = tmp;
                int b = cnt[i];
                tmp = _gcd(a, b);
                if(tmp == 1)
                    break;
            }
            if(tmp == 1)
                printf("0\n");
            else
            {
                int ans = 0;
                for(int i=0;i<ball_num;++i)
                    ans += (cnt[i]/tmp);
                printf("%d\n",ans);
            }
        }
    }
    return 0;
}

第二题

题意

       求矩阵的最长上升序列的长度。

思路

       题意里没说四方向还是八方向,我按照四方向做的。dfs+记忆化,以矩阵中的每个点当做起点做dfs,寻找最长上升序列,最后输出最长的就行了。以下为AC代码。

代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<string>

using namespace std;

int m,n;
int dirx[5]={0,-1,0,1};
int diry[5]={-1,0,1,0};

int dfs(vector<vector<int> > &num, vector<vector<int> > &dp, int si, int sj)
{
    if(dp[si][sj])
        return dp[si][sj];
    int ans = 1;
    for(int i=0;i<4;++i)
    {
        int x = si + dirx[i];
        int y = sj + diry[i];
        if(x<0 || x>=m || y<0 || y>=n || num[x][y]<=num[si][sj])
            continue;
        int len = dfs(num, dp, x, y) + 1;
        ans = max(ans, len);
    }
    dp[si][sj] = ans;
    return ans;
}

int main()
{
    while(scanf("%d %d",&m, &n)!=EOF)
    {
        vector<vector<int> > num(m);
        for(int i=0; i<m; ++i)
        {
            for(int j=0; j<n; ++j)
            {
                int tmp;
                scanf("%d",&tmp);
                num[i].push_back(tmp);
            }
        }
//        for(int i=0;i<m;++i)
//        {
//            for(int j=0;j<n;++j)
//                cout<<num[i][j];
//            cout<<endl;
//        }
        vector<vector<int> > dp(m, vector<int>(n,0));
        int ans = 1;
        for(int i=0; i<m; ++i)
            for(int j=0; j<n; ++j)
                ans = max(ans, dfs(num, dp, i, j));
        printf("%d\n",ans);
    }
    return 0;
}

版权声明:本文为ms961516792原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。