分享一下今日头条的在线笔试编程题第一题的一些思路

    笔试的岗位是服务端开发,采用的语言是c++。说下自己的编程题ac情况,第一道ac90%,第二道没时间调试啦。这种情况,实在不好意思分享
自己的思路,都没ac过。但是自己真的想了好久,还是想和大家分享一下,相互学习嘛。
     第一题编程的提示点,我觉得有以下几点:
     1.难度要求,提示难度是要有序的,最大差值不能大于10,其实这个很多都能想到排序。
     2.难度的范围是1到100
     这道题,我觉得有几个特殊情况是不好处理的,比如(以3题为例子):
     1.20 70 90
      2.17 70 90
      3.50 50 50
     分享我的思路
     1.排序
     刚开始我使用的是c++算法中sort排序,懒得自己写什么快排啦,主要怕出错,还得浪费时间调试,重点可不是排序。
     但是如果出现的难道都是一样的,一般排序效果就不太好了。但是我不确定题目会不会出现这样的情况,也可能自己意淫的,哈哈。
     注意到难度是处于1到100之间,其实可以采用桶排序,只要101个桶就行,空间复杂度是O(1),时间复杂度为O(n)
     2.确定两个数之间大于10时要插入数的个数
     主要处理两种情况,如:1.20与70之间,其实是要4个
                           2.17与70之间,却要5个
      3.注意是三道题是一份卷,总的数量必须是3的倍数
    
     说了这么多,贴代码(有点乱,主要当时时间紧):

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int getTi(vector<int> v, int n,int m)
{
	int count = 0;
	int len = n;
	for (int i = 0; i < len-1; i++)
	{
		//比较两个数的间隔
		int tmp = v[i + 1] - v[i];
		//大于10,表示要插入数进行填充,来满足小于等于10
		/*
		这里分两种情况,比如20、70、90
		70-20等于50,但是要插4个
		70-17等于53,要插5个
		所以分了两种情况,是10的整倍数和不是
		*/
		if (tmp>10)
		{
			if (tmp % 10)
			{
				count += tmp / 10;
			}
			else
			{
				count += tmp / 10;
				count -= 1;
			}
		}
	}
	/*
	因为三道题为一组,所以必须总数为3的倍数
	*/
	if ((count + m) % 3)
	{
		count += 3-(count + m) % 3;
	}
	return count;
}
int getTi2(vector<int> v, int n)
{
	//排序,采用桶排序
	/*
	为什么采用桶排序,是因为,如果遇到30,30,30...这种情况的话,一般的排序避免不了
	桶排序是以空间换时间,你会发现难度是不超过100的,所以用101个桶就可以把所有的情况包括,空间复杂度为O(1),
	时间复杂度为O(N)
	*/
	vector<int> d;
	for (int i = 0; i <101; i++)
	{
		d.push_back(0);
	}
	for (int i = 0; i < n; i++)
	{
		if (!d[v[i]])
		{
			d[v[i]] = 1;
		}
	}
	int k = 0;
	for (int i = 0; i < 101; i++)
	{
		if (d[i])
		{
			v[k++] = i;
		}
	}
	//排序完交给getTi函数,真正的核心
	return getTi(v, k, n);
}
int main()
{
	int n;
	vector<int> v;
	//处理输入
	while (cin >> n)
	{
		v.clear();
		int num;
		for (int i = 0; i < n; i++)
		{
			cin >> num;
			v.push_back(num);
		}
		//真正处理程序
		int count = getTi2(v, n);
		cout << count << endl;
	}
	//暂定等待输出,这个忽略,这个在vs中使用,gcc不需要
	system("pause");
	return 0;
}

#字节跳动#
全部评论
你跟我一样的思路 我也是90% 不过我现在想明白了 举个例子 给的数组是1、2、10、50 按你的思路10跟50之间应该插入3个数 但实际上只有插入两个就可以了 例如插入30和40 就可以分成1、2、10和30、40、50两组 所以这种思路其实是有问题的。 其实,每次最多只能插入2个数,你想想是不是? 只用区分两种情况,一种是相邻两个数相差在10到20之间 那么我们要插入一个,另一种是如果相邻相差大于20了,那么就插入两个,最后再去补全,直到数组中元素个数是3的倍数。
点赞 回复 分享
发布于 2016-09-21 23:27
楼主想的有点复杂了。我来说一说我的思路。AC了的。 第一步先 排序。这个大家都能想到。 第二步,三个为一组。首先看前三个 a1,a2,a3.    FIRST 如果a2-a1<=10&&a3-a2<=10 则符合要求,就从第4个开始,a4,a5,a6为一组。。。 SECOND 如果 a2-a1>10 && a2-a1<=20 则 数量+1,跳到第3个,a3,a,4,a5为一组。。。 THIRD  如果 a2-a1>20  则数量 +2;跳到第2 个,a2,a3,a4,为下一组。。 FOURTH 如果 a2-a1<=10,a3-a2>10,则数量+1,跳到第3个,a3,a4,a5为下一组。。。。 #include<iostream> #include<vector> #include<algorithm> using namespace std; int main() { int n; while(cin>>n) { vector<int> ivec; for(int i=0;i!=n;++i) { int temp; cin>>temp; ivec.push_back(temp); } sort(ivec.begin(),ivec.end()); int sz=ivec.size(); int count=0; int zou; for(zou=0;zou+2<sz;) { if(zou+2<sz) { if(ivec[zou+1]-ivec[zou]>10&&ivec[zou+1]-ivec[zou]<=20) {count+=1; zou+=2; continue; } if(ivec[zou+1]-ivec[zou]>20) { count+=2; ++zou; continue; } if(ivec[zou+1]-ivec[zou]<=10&&ivec[zou+2]-ivec[zou+1]>10) { ++count; zou+=2; continue; } zou+=3; } } if(sz-zou==2) { if(ivec[zou+1]-ivec[zou]<=10) { count+=1; cout<<count<<endl; break; } if(ivec[zou+1]-ivec[zou]>10&&ivec[zou+1]-ivec[zou]<=20) { count+=1; cout<<count<<endl; break; } if(ivec[zou+1]-ivec[zou]>20) { count+=4; cout<<count<<endl; break; } } if(sz-zou==1) { count+=2; } cout<<count<<endl; } }
点赞 回复 分享
发布于 2016-09-21 23:24
这写的没啥意义啊,都不知道你说的是啥题
点赞 回复 分享
发布于 2017-03-29 21:32

相关推荐

不愿透露姓名的神秘牛友
11-26 18:54
说等下个版本吧的发呆爱好者很贪睡:佬最后去了哪家呀
点赞 评论 收藏
分享
巧克力1:双选会不如教室宣讲会
点赞 评论 收藏
分享
冲芭芭拉鸭:你这图还挺新,偷了。
投递美团等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务