创新工场二面的面试官,问了本人一个题目,本人直接就跪在那里了!题目如下:
4=1+1+1+1
4=1+1+1+1
=1+1+2
=1+3
=2+2
例如 数字4 可以被拆解成为如上的四种情况。那么本人现在给你一个vector< vector<int> > 你把全部的结果全部的保存到这个
vector< vector<int> > 中。
函数的函数体,应该是这个样子的 vector< vector<int> > & fun(int n){ //函数体 }
让本人写出这个函数的代码,但是本人写不出来,甚至连算法本人 都没有思路。
可能大家觉的4还是很容易的 ,但是本人给你100,那么:
100=59+41
=58+42
=57+43
。
=1+99
=1+1+98
=1+1+97
等等 结果非常的多 本人也不知道该怎么样拆分
解决方案:10分
有时间限制吧?面试的时候考这个确实挺难了,一小时才写出来,效率也比较低。
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
bool sort_by( const int &v1, const int &v2)
{
return v1 < v2;
}
void invternal(vector<vector<int>> &vv, int n)
{
vector<int> vs;
if (n == 1)
{
vs.push_back(1);
vv.push_back(vs);
return;
}
else
{
vector<vector<int>> oo;
invternal(oo, n - 1);
if (n == 4)
{
int a = 1;
}
vector<vector<int>> os = oo;
vector<vector<int>>::iterator us;
vector<int>::iterator uv;
for (us = oo.begin() ; us != oo.end() ; us++)
{
us->push_back(1);
sort(us->begin(), us->end(), sort_by);
}
int ita = 0;
int itb = 0;
for (us = os.begin() ; us != os.end() ; us++, ita++)
{
vector<int> xs;
set<int> mm;
itb = 0;
for (uv = us->begin() ; uv != us->end() ; uv++, itb++)
{
if (mm.find(*uv) == mm.end() && *uv < n - 1)
{
xs = *us;
xs[itb]++;
mm.insert(*uv);
sort(xs.begin(), xs.end(), sort_by);
vector<vector<int>>::iterator un;
for (un = oo.begin() ; un != oo.end() ; un++)
{
if (*un == xs)
{
break;
}
}
if (un == oo.end())
{
oo.push_back(xs);
}
}
}
}
vv = oo;
}
}
vector<vector<int>> &fun(int n)
{
vector<vector<int>> *vv = new vector<vector<int>>;
if (n <= 0)
{
return *vv;
}
invternal(*vv, n);
return *vv;
}
int main()
{
vector<vector<int>> &uu = fun(7);
getchar();
return 0;
}
解决方案:10分
#include <stdio.h>
#include <stdlib.h>
void print(int res[], int num) {
static int L=0;
L++;
printf("%8d:",L);
for (int i=0;i<num;++i) {
printf(" %d", res[i]);
}
printf("\n");
}
void split(int n, int m) {// n表示总数,m表示最大因子
static int res[100];// 保存结果
static int num=-1;// 当前因子下标
if (n<m || n<0 || m<1) return;
num++;
if (0==n) {// 递归终止条件,为0不可再分,直接输出
print(res,num+1);
num--;
return;
} else {
if (n==m) {// 不拆,直接输出
res[num]=m;
print(res,num+1);
num--;
} else {
// 拆分出第一个
res[num]=m;
n=n-m;
if (m>n) m = n; // 最大因子不可能大于总数
for (int i=m;i>=1;--i) {// 循环,第二个因子可以继续拆分,而且按照最大因子不同可以拆分成多个
split(n,i);
}
num--;
}
}
}
void Split(int n) {
if (n<=0) return;
if (100<n) {
printf("Up to 100\n");
return;
}
for (int i=n;i>=1;--i) {
split(n, i);
}
}
void main(int argc,char **argv) {
if (argc<=1) Split(5);
else if (argc>=3) split(atoi(argv[1]),atoi(argv[2]));
else Split(atoi(argv[1]));
}
解决方案:10分
#include <iostream>
#include <vector>
using namespace std;
vector< vector<int> > split(int number, int head)
{
int begin = head, end = head;
vector< vector<int> > vvint;
while (begin + end <= number) {
vector<int> vint;
int temp = number - begin - end;
vint.push_back(begin);
for (int i = 0; i < temp; i++)
vint.push_back(1);
vint.push_back(end);
vvint.push_back(vint);
end++;
}
return vvint;
}
vector < vector<int> > totalSplit(int number)
{
vector < vector<int> > totalVvint;
vector < vector<int> > vvint;
int head = 1;
do {
vvint = split(number, head++);
for (unsigned int i = 0; i < vvint.size(); i++)
totalVvint.push_back(vvint.at(i));
} while(!vvint.empty());
return totalVvint;
}
void printSplit(vector < vector<int> > totalVvint)
{
for (unsigned int i = 0; i < totalVvint.size(); i++) {
vector<int> vvint = totalVvint.at(i);
for (unsigned int j = 0; j < vvint.size(); j++) {
cout << vvint.at(j) << " ";
}
cout << endl;
}
cout << endl;
}
int main()
{
cout << "number : " << 4 << endl;
printSplit(totalSplit(4));
cout << "number : " << 10 << endl;
printSplit(totalSplit(10));
return 0;
}
输出结果: