您的位置:首页 > 其它

腾讯2017暑期实习生笔试题(有趣数字)

2016-09-06 21:43 288 查看
   之前准备把腾讯实习生招聘的第三道题做出来的,但是时间很紧,最终拖到今天才完成的,下午做了一个小时才弄出来的,主要是细节方面的问题。





这个题意思很简单吧,给出很多数,找出“二元组”里面差最小的和差最大的个数(两个数的差事大的减去小的,也就是绝对值的意思)。说实话,这个题的处理确实很难把握。

    我的解题思路是:先将这个数组排序,然后就很容易计算出差最大的二元组的个数,接下来就是计算最小二元组的个数。

最大二元组的计算是分别计算出最大值和最小值(可能存在重复,需要把握住),假设最小值的个数为n,最大值的个数为m,那么差最大的二元组的个数即为:n*m,若是不明白
  


 

最小二元组的计算则相对复杂一些,但是排序以后,最小差距的计算就是计算相邻两个数的差。其中需要把握的东西就是计算过程中”差距“由一个值变为另一个值的时候需要好好把握,这个时候很容易出错。我按照我写的代码来讲述,大家可以根据我所说的自己再设计代码,主要是一些细节的变化。还需要注意的一点就是,最小差并不一定是连续的,可能会间隔一些,我给个例子,大家对照着看看吧。



我写的代码会刚开始的时候跳过对开始部分的两个4的统计,最小值跟给出的值总是想差一点点,最后发现问题是出在两次最小差改变的时候,下面给出代码,供参考一下。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void Solution(vector<int>& V){
int sz = V.size();
int min = 0;
int minNum = 0;//最小二元组数目
int maxNum = 0;//最大二元组数目
if (sz == 0){
cout << 0 << " " << 0 << endl; //差最小,差最大
return;
}
else if (sz == 1){
cout << 1 << " " << 1 << endl;
}
else{
sort(V.begin(), V.end()); //排序

int i = 0;
int j = sz - 1;

while (V[i] == V[i + 1] && i < sz - 1){
++i;
}
while (V[j] == V[j - 1] && j > 0){
--j;
}
maxNum = (i + 1)*(sz - j); //差最大的数

min = V[sz - 1] - V[0] + 1;
int flag = 0;
for (int k = 0; k < sz - 1; ++k)
{
if (V[k + 1] - V[k] < min){
min = V[k + 1] - V[k];
minNum = 1;
flag = 1; //主要用于记录差距第一次变为0
if (min == 0)
{
--k; //这样做的目的是为了不错过min=0的,第一次统计的时候会少统计一个
}
}
else if (V[k + 1] - V[k] == min){
int sum = 0;
while (k< sz -1 && V[k + 1] - V[k] == min)
{
++k;
++sum;
}

if (min == 0){	//差距为0
if (flag == 1){
minNum = (sum)*(sum + 1) / 2; //差距一次变为0的时候需要好好注意
flag = 0;
}
else{
minNum += sum*(sum + 1) / 2;//根据相同元素个数计算二元组个数
}
}
else{ //差距不为0
minNum += sum;
--k;  //k会加两次(for循环也会加一次,所以需要调整一下)
}
}
}
}
cout << minNum << " " << maxNum << endl;
}

int main()
{
int n;
int tmp;
while (cin >> n){
vector<int> arr;
for (int i = 0; i< n; ++i){
cin >> tmp;
arr.push_back(tmp);
}
Solution(arr);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法