2018秋招编程题汇总

版权声明:转载标明出处 https://blog.csdn.net/qq_38289815/article/details/82586653

1.商汤的一道填空题(我觉得可以改成编程题做)

#include <iostream>
using namespace std;
int count = 0;
void Perm(int a[], int k, int m)  //Perm函数用来解决排列问题
{
	int i;
	if(k == m)
	{
		if(a[5] > a[0] && a[6] > a[1])
		{
			if(a[7] > a[2] && a[8] > a[3] && a[9] > a[4])
			{
				if(a[4] > a[3] && a[3] > a[2] && a[2] > a[1] && a[1] > a[0])
				{
					if(a[9] > a[8] && a[8] > a[7] && a[7] > a[6] && a[6] > a[5])
					{
						for(i = 0; i <= 4; i++)
							cout << "[" <<a[i] << "]";
						cout <<endl;
						for(i = 5; i <= 9; i++)
							cout << "[" << a[i] << "]";
						cout <<endl;
						cout << "-----------------" <<endl;
                                                count++;
					}
				}
			}
		}
	}
	else
		for(int i = k; i <= m; i++)
		{
			swap(a[k],a[i]);
			Perm(a, k+1, m);
			swap(a[k], a[i]);
		}
}

	template <class T>
void swap(T &a, T &b)
{
	T temp = a;
	a = b;
	b = temp;
}

int main()
{
	int a[10] = {5,4,3,2,1,6,7,8,9,10};
	Perm(a, 0, 9);
        cout << "Count:" << count <<endl;
	return 0;
}

这题要是会排列算法解题就会轻松很多,之后就是在排列算法中加入限制条件即可。

2.百词斩

#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;

int Asd(char *p, char *q, int sumlen, int len, int n)
{                             //*p指向数组,*q指向字符串
    int i,j,flag,k = 0;       //sumlen是数组的长度,len是输入字符串的长度,n是列
    for(j = 0; j < len; j++)
    {
        flag = 0;
        for(i = 0; i < sumlen; i++)
        {
           if(p[i] == q[j] && j == 0)
           {
                flag = 1; //flag
           }
           if(p[i] == q[j] && (p[i-1] == q[j-1] || p[i+1] == q[j-1] || p[i-n] == q[j-1] || p[i+n] == q[j-1]))
           {
                flag = 1;
                if(flag == 1 && j == len-1)
                {
                    return 1;
                }
           }
        }
        if(flag == 0)
        {
            break;
            return 0;
        }
    }
}

int main()
{
    int i = 0,m,n,sum;
    char *p;
    char a;
    string s1;
    cin >> m >> n;
    sum = m*n;
    p = new char[sum];      //常规操作,创建数组
    int j = sum;
    while(j > 0)            //输入
    {
        cin >> a;
        if(a >= 'A' && a <= 'Z' || a >= 'a' && a <= 'z')
        {
            p[i++] = a;
            j--;
        }
    }

    cin >> s1;
    int strlength = s1.length();
    const char *r = s1.data();
    char *q = const_cast<char*>(r);   //string转char*

    int reasult = Asd(p, q, sum, strlength, n);

    if(reasult == 1)
        cout << "true" <<endl;
    else
        cout << "false" <<endl;
    return 0;
}

读懂题就好,整体不难。其中有一段代码时string转const char*的,可以不用那么做,我这样写也只是想用以下data()函数而已。

3.thoughtworks的作业

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;

void Change(char *mat, int *asd, int q, int w);
void Display(char *mat, int x, int m)
{
	int i;
	for(i = 0; i < x; i++)
	{
		if(i%(2*m+1) == 0 && i > 0)
			cout <<endl;
		cout << "[" << mat[i] << "]" << " ";
	}

}

void Initall(char *mat, int x)
{
	int i;
	for(i = 0; i < x; i++)//初始化墙
	{
		mat[i] = 'W';
	}
}

void Init(char *mat, int n, int m)
{
	int i,j,k;
	for(i = 1; i < 2*n+1; i = i+2)
	{
		for(j = 1; j < 2*m+1; j = j+2)
		{
			*(mat + i*(2*m+1) + j) = 'R';
		}
	}
}

void Input(char *mat, int q, int w)
{
	char str[100] = "0,1 0,2;1,0 1,1;1,2 1,1;2,1 2,0;0,0 1,0;0,2 1,2;1,1 2,1;1,2 2,2;0,1 1,1";
	char *p1 = str;
	char *p2, *p3, *p4;
	int asd[4] = {0};
	int a,x,y,length,k = 0,i = 0;
	printf("%s\n", str);
	int len = strlen(str);
	p2 = strtok(p1, ";");
	while((len > 0) && (p2 = strtok(p1, ";")) != (char *)NULL)
	{
		p1 += strlen(p2) +1;
		len -= strlen(p2) +1;
		length = strlen(p2)+1;
		while(length > 0 && (p3 = strtok(p2, " ")) != (char *)NULL)
		{
			p2 += strlen(p3) + 1;
			length -= strlen(p3) + 1;
			if (i == 4)
				i = 0;
			if (k == 4)
				k = 0;
			while((p4 = strtok(p3, ",")) != (char *)NULL)
			{		
				a = atoi(p4);
				asd[i++] = a;
				p3 = (char *)NULL;
				k++;
				if (i == 4 && k == 4)//判断什么时候传数据
				{
					Change(mat, asd, q, w);
				}
			}
		}
	}
}

void Change(char *mat, int *asd, int q, int w)
{
	int a,b,x,y;
	int m,n;
	a = asd[0];
	b = asd[1];
	x = asd[2];
	y = asd[3];
	if(a == x || b == y)//此时是上下左右的关系
	{
		if(a == x)//行相等
		{
			m = 2*a+1; 
			if(b < y)
				n = 2*b+2;  //n是转换后的列
			else
				n = 2*y+2;
			*(mat + (m*(2*w+1)) + n) = 'R';

		}

		else//列相等
		{
			n = 2*b+1; 
			if(a < y)
				m = 2*(a)+2;
			else
				m = 2*(y)+2;
			*(mat + (m*(2*w+1)) + n) = 'R';
		}
	}
	else
	{
		cout << "Maze format error!" <<endl;
	}
}

int main()
{
	int n,m;//n是行,m是列
	char *p;
	cout << "输入行列数:";
	cin >> n >> m;
	int x = (2*n+1)*(2*m+1);
	p = new char[x];
	Initall(p, x);
	cout << "Output:" <<endl;
	Init(p, n, m);
	Input(p, n, m);
	Display(p, x, m);	
	cout <<endl;
	return 0;
}

这是测试代码,只要把输入修改以下就可以了,难点就是字符串的分割(不要在意代码量和时间、空间复杂度,做出来就没有心思优化了)。

4.京东(开发&测试都有)

#include <iostream>
#include <vector>
#include <algorithm>
#define N 20000

using namespace std;
int n_temp[N], temp_to[N], f_temp[N], res, temp_v;
int x[N], y[N];
int tot = 0, po, mtemp;
void fundfs(int u, int bu, int dis, int index_x, int index_y)
{
	if (dis>mtemp) { mtemp = dis; po = u; }
	for (int e = f_temp[u]; e; e = n_temp[e])
	{
		temp_v = temp_to[e];
		if (temp_v != bu && (!((u == index_x && temp_v == index_y) || (u == index_y && temp_v == index_x))))
		{
			fundfs(temp_v, u, dis + 1, index_x, index_y);
		}
	}
}

void funcreate(int a, int b)
{
	tot++;
	n_temp[tot] = f_temp[a];
	f_temp[a] = tot;
	temp_to[tot] = b;
}
int main()
{
	int n;
	cin >> n;
	for (int i = 0; i<n - 1; ++i)
	{
		cin >> x[i] >> y[i];
		funcreate(x[i], y[i]);
		funcreate(y[i], x[i]);
	}
	for (int i = 0; i<n - 1; ++i)
	{
		mtemp = 0; po = 0;
		fundfs(x[i], 0, 0, x[i], y[i]);
		fundfs(po, 0, 0, x[i], y[i]);
		int tmp = mtemp; mtemp = 0; po = 0;
		fundfs(y[i], 0, 0, x[i], y[i]);
		fundfs(po, 0, 0, x[i], y[i]);
		if (tmp*mtemp>res) res = tmp*mtemp;
	}
	cout << res << endl;
	return 0;
}

网上大牛写的代码,我还在看。

5.美团(后台开发)

小明拿到一个数列a1,a2,…an,小明想知道存在多少个区间[l,r]同时满足下列两个条件:

(1)r - l + 1 = k;
(2)在al,al+1,…ar中存在一个数至少出现t次

输出满足条件的区间个数。 
输入:

输入一行三个整数:n,k,t(1<=n,k,t<=10^5)
第二行n个整数:a1,a2,…an(1<=ai<=10^5)

样例输入:

5 3 2 
3 1 1 1 2

样例输出:

3

Hint

区间[1,3]中1出现了2次,区间[2,4]中1出现了3次,区间[3,5]中1出现了2次,使用一共有3个区间满足条件

牛客网WAK的思路:
先判断n和k的关系,若k>n,直接返回0,若k<n,再进行后续计算
设置一维数组lst[10005],保存数列中值出现次数
设置count,保存ar-al中出现t次及以上数的个数
设置num,保存区间数
首先从0到n-k-1遍历一遍,对lst、count、num进行初始化
然后将窗口向右滑动,每次从头去一个,从尾部添加一个,动态维护lst、count、num的值,最后输出num的值即可

#include<bits/stdc++.h>
using namespace std;
int lst[10005];
int main(){
    int n,k,t;
    while(cin>>n>>k>>t)
    {
        if(k<=n)
        {
            vector<int> vec;
            memset(lst,0,sizeof(lst));
            for(int i = 0;i<n;i++)
            {
                int x;
                cin>>x;
                vec.push_back(x);
            }
        int count = 0;
        int num = 0;
        for(int i = 0;i<k;i++)
        {
            lst[vec[i]]++;
            if(lst[vec[i]]==t)
            count++;
        }
        if(count>0)
            num++;
        for(int i = 0;i<n-k;i++)
        {
            lst[vec[i]]--;
            if(lst[vec[i]]==t-1)
            count--;
            lst[vec[i+k]]++;
            if(lst[vec[i+k]]==t)
                count++;
            if(count>0)
                num++;
        }
        cout<<num<<endl;
        }//if(k<=n)
        else
            cout<<0<<endl;
    }
    return 0;
}

6.美团(后台开发)

给定一张包含N个点、N-1条边的无向连通图,节点从1到N编号,每条边的长度均为1。假设你从1号节点出发并打算遍历所有节点,那么总路程至少是多少?
输入
第一行包含一个整数N,1≤N≤100000。
接下来N-1行,每行包含两个整数X和Y,表示X号节点和Y号节点之间有一条边,1≤X,Y≤N。
输出
输出总路程的最小值。

牛客网WAK的思路:走完所有节点类似于深度优先搜索,也就是说除了最后一条路径外,别的路径都经历了正着走,再返回
的过程,也就是两遍,设最后一条路径为x,总分支数为n-1,总路径=2*(n-1-x)+x=2*n-2-x,当x最大时,总路径最小,所以转化为求多叉树的深度。

输入:                输入:
6                    6
1 3                  1 2
3 6                  1 3
6 4                  1 5
4 5                  1 4
5 2                  4 6
输出:5              输出:8
        
#include<bits/stdc++.h>
using namespace std;
int lst[100005];
int main(){
    int n;
    while(cin>>n)
    {
        memset(lst,0,sizeof(lst));
        for(int i = 0;i<n-1;i++)
        {
            int a,b;
            cin>>a>>b;
            lst[b] = lst[a]+1;//当前节点的深度
        }
        int depth = 0;
        for(int i = 1;i<=n;i++)
            depth = lst[i]>depth?lst[i]:depth;//找到最大值
        cout<<2*n-2-depth<<endl;
    }
    return 0;
}

(先整理这么多吧,持续更新中)

猜你喜欢

转载自blog.csdn.net/qq_38289815/article/details/82586653