面试总结:任意一个整数分解为几个连续正整数之和
2014-11-18 09:34
405 查看
前阵子参加了国内某一大公司的面试。到了之后,人家不问出身,不问来历,就直接开机让我上机编程。因为是第一次在面试时上机操作,尽管题目不是很难,但是由于没搞清楚机考和笔试的区别,导致最后面试失败。现在总结一下自己在机考时碰到的一些问题,以免自己以后再犯同样的错误。不多说了,直接上题。
下面这道题,其实有代码更简洁或者算法复杂度也比较低的解法,这里不作讨论,这里的重点是指出面试时一些机考和笔试的区别。
题目描述:一个正整数有可能可以被表示为n(n>;=2)个连续正整数之和,如:
15=1+2+3+4+5
15=4+5+6
15=7+8
请编写程序,根据输入的任何一个正整数,找出符合这种要求的所有连续正整数序列。
输入数据:一个大于0并且不大于100正整数,以命令行参数的形式提供给程序。
输出数据:1.在标准输出上打印出符合题目描述的全部正整数序列,每个序列都从改序列的最小正整数开始,以从小到大的顺序打印
2.如果结果有多个序列,按各序列的最小正整数的大小从小到大打印个序列
3.序列不允许重复,序列内的整数用一个空格分隔,序列之间用英文“,”分隔
4.如果没有符合要求的序列,输出“NONE”,如果输入不符合要求,则输出“ERROR”
样例输入:15
样例输出:1 2 3 4 5,4 5 6,7 8
估计很多人面试时看到这样的题目,心里都会在偷偷的笑,是的,我也笑了。不过,我只看到了故事的开头,却没猜到故事的结尾。下面是我当时提交的第一份代码:
#include <iostream>
using namespace std;
int main()
{
int nSplitNum = 0;
cout << "请输入一个大于0并且不大于100的整数:";
cin >> nSplitNum;
//判断合法性
if (nSplitNum < 1 || nSplitNum > 100)
{
cout << "ERROR" << endl;
return 1;
}
bool bFlag = false; //记录是否有符合要求的序列
for (int i = 1; i <= nSplitNum / 2; i++)
{
int nSum = i;
for (int j = i + 1; j < nSplitNum; j++)
{
nSum += j;
if (nSum > nSplitNum)
{
break;
}
else if (nSum == nSplitNum)
{
//如果相等,循环输出序列
for (int k = i; k <= j; k++)
{
cout << k;
if (k != j)
{
cout << " "; //序列最后一个数字时,不用输出“ ”
}
}
cout << ","; //序列之间用“,”隔开
bFlag = true;
break;
}
}
}
if (!bFlag)
{
cout << "NONE" << endl;
return 1;
}
cout << endl;
system("pause");
return 0;
}
输出的结果如图:
乍看之下,这份代码是没有什么问题的,输入任意一个在1~100范围内的整数,也能够正确输出分解后的序列,排序也没有问题。如果是在笔试,这样写基本就算是对了。但在机考时,机器却给了我零分,说我测试一个都没通过。
看到这个分数,我楞了楞,开始检查自己的代码,发现算法肯定是没问题的,那么会不会问题出在结果上呢?可以看到我输出的序列的最后还多了一个英文逗号“,”,会不会是这个地方导致了测试没通过呢?在我上面的代码中,我是在序列最后输出英文逗号“,”的,但是我没办法判断哪个序列是最后一个序列,也就没办法禁止最后一个英文逗号“,”的输出显示了。
既然不能在序列的最后输出英文逗号“,”,那么就考虑放到序列的前面去输出显示。只要从第二个序列开始,在序列的前面加上英文逗号“,”就可以了,下面是我当时提交的第二份代码:
#include <iostream>
using namespace std;
int main()
{
int nSplitNum = 0;
cout << "请输入一个大于0并且不大于100的整数:";
cin >> nSplitNum;
//判断合法性
if (nSplitNum < 1 || nSplitNum > 100)
{
cout << "ERROR" << endl;
return 1;
}
static bool bFirst = true; //记录是否是第一个序列
bool bFlag = false; //记录是否有符合要求的序列
for (int i = 1; i <= nSplitNum / 2; i++)
{
int nSum = i;
for (int j = i + 1; j < nSplitNum; j++)
{
nSum += j;
if (nSum > nSplitNum)
{
break;
}
else if (nSum == nSplitNum)
{
//如果相等,循环输出序列
if (!bFirst)
{
cout << ","; //从第二个序列开始,在序列的前面加上英文逗号“,”
}
bFirst = false;
for (int k = i; k <= j; k++)
{
cout << k;
if (k != j)
{
cout << " "; //序列最后一个数字时,不用输出“ ”
}
}
bFlag = true;
break;
}
}
}
if (!bFlag)
{
cout << "NONE" << endl;
return 1;
}
cout << endl;
system("pause");
return 0;
}
输出的结果如图:
很遗憾,结果还是零分,一个测试也没通过。当时做到这里,确实有点急了,毕竟这是在面试,时间不等人啊。只能回头重新看题目了,到底是什么导致测试通不过呢?当我重新看到最后的样列输入时,突然想到既然输出可能有要求,那么输入是不是可能也有要求呢?于是我决定把中文提示去掉试试,下面是我提交的第三份代码:
#include <iostream>
using namespace std;
int main()
{
int nSplitNum = 0;
cin >> nSplitNum;
//判断合法性
if (nSplitNum < 1 || nSplitNum > 100)
{
cout << "ERROR" << endl;
return 1;
}
static bool bFirst = true;
bool bFlag = false; //记录是否有符合要求的序列
for (int i = 1; i <= nSplitNum / 2; i++)
{
int nSum = i;
for (int j = i + 1; j < nSplitNum; j++)
{
nSum += j;
if (nSum > nSplitNum)
{
break;
}
else if (nSum == nSplitNum)
{
if (!bFirst)
{
cout << ",";
}
bFirst = false;
//如果相等,循环输出序列
for (int k = i; k <= j; k++)
{
cout << k;
if (k != j)
{
cout << " "; //序列最后一个数字时,不用输出“ ”
}
}
bFlag = true;
break;
}
}
}
if (!bFlag)
{
cout << "NONE" << endl;
return 1;
}
cout << endl;
system("pause");
return 0;
}
输出结果如图:
至此,终于提示测试全部通过!不过,这却影响到了我的面试结果。。。。。。
简简单单的题目,在机考时却几经波折,可见在机考时,不仅要确保代码正确,还要严格按照给出的输入输出格式进行显示。在普通的笔试中,只要关键代码部分写对了,面试官一般就会认为你掌握相应的知识了,所以机考的难度明显要大于笔试的难度。同时机考时需要注意一些更加细节的地方,由于是机器判卷,只要稍有不合理其规则的地方,就会导致全部被判断出错,就比如我这里第二份代码中的“请输入一个大于0并且不大于100的整数”这样的一个提示,在平时的Win32程序编写中,加上这个提示会显得人性化一点,但是这道题里已经给出了样例输入,如果加了那么肯定就错了。因此,在机考时还要注意自己在平时的一些编程习惯是否和题目的要求相吻合。
下面这道题,其实有代码更简洁或者算法复杂度也比较低的解法,这里不作讨论,这里的重点是指出面试时一些机考和笔试的区别。
题目描述:一个正整数有可能可以被表示为n(n>;=2)个连续正整数之和,如:
15=1+2+3+4+5
15=4+5+6
15=7+8
请编写程序,根据输入的任何一个正整数,找出符合这种要求的所有连续正整数序列。
输入数据:一个大于0并且不大于100正整数,以命令行参数的形式提供给程序。
输出数据:1.在标准输出上打印出符合题目描述的全部正整数序列,每个序列都从改序列的最小正整数开始,以从小到大的顺序打印
2.如果结果有多个序列,按各序列的最小正整数的大小从小到大打印个序列
3.序列不允许重复,序列内的整数用一个空格分隔,序列之间用英文“,”分隔
4.如果没有符合要求的序列,输出“NONE”,如果输入不符合要求,则输出“ERROR”
样例输入:15
样例输出:1 2 3 4 5,4 5 6,7 8
估计很多人面试时看到这样的题目,心里都会在偷偷的笑,是的,我也笑了。不过,我只看到了故事的开头,却没猜到故事的结尾。下面是我当时提交的第一份代码:
#include <iostream>
using namespace std;
int main()
{
int nSplitNum = 0;
cout << "请输入一个大于0并且不大于100的整数:";
cin >> nSplitNum;
//判断合法性
if (nSplitNum < 1 || nSplitNum > 100)
{
cout << "ERROR" << endl;
return 1;
}
bool bFlag = false; //记录是否有符合要求的序列
for (int i = 1; i <= nSplitNum / 2; i++)
{
int nSum = i;
for (int j = i + 1; j < nSplitNum; j++)
{
nSum += j;
if (nSum > nSplitNum)
{
break;
}
else if (nSum == nSplitNum)
{
//如果相等,循环输出序列
for (int k = i; k <= j; k++)
{
cout << k;
if (k != j)
{
cout << " "; //序列最后一个数字时,不用输出“ ”
}
}
cout << ","; //序列之间用“,”隔开
bFlag = true;
break;
}
}
}
if (!bFlag)
{
cout << "NONE" << endl;
return 1;
}
cout << endl;
system("pause");
return 0;
}
输出的结果如图:
乍看之下,这份代码是没有什么问题的,输入任意一个在1~100范围内的整数,也能够正确输出分解后的序列,排序也没有问题。如果是在笔试,这样写基本就算是对了。但在机考时,机器却给了我零分,说我测试一个都没通过。
看到这个分数,我楞了楞,开始检查自己的代码,发现算法肯定是没问题的,那么会不会问题出在结果上呢?可以看到我输出的序列的最后还多了一个英文逗号“,”,会不会是这个地方导致了测试没通过呢?在我上面的代码中,我是在序列最后输出英文逗号“,”的,但是我没办法判断哪个序列是最后一个序列,也就没办法禁止最后一个英文逗号“,”的输出显示了。
既然不能在序列的最后输出英文逗号“,”,那么就考虑放到序列的前面去输出显示。只要从第二个序列开始,在序列的前面加上英文逗号“,”就可以了,下面是我当时提交的第二份代码:
#include <iostream>
using namespace std;
int main()
{
int nSplitNum = 0;
cout << "请输入一个大于0并且不大于100的整数:";
cin >> nSplitNum;
//判断合法性
if (nSplitNum < 1 || nSplitNum > 100)
{
cout << "ERROR" << endl;
return 1;
}
static bool bFirst = true; //记录是否是第一个序列
bool bFlag = false; //记录是否有符合要求的序列
for (int i = 1; i <= nSplitNum / 2; i++)
{
int nSum = i;
for (int j = i + 1; j < nSplitNum; j++)
{
nSum += j;
if (nSum > nSplitNum)
{
break;
}
else if (nSum == nSplitNum)
{
//如果相等,循环输出序列
if (!bFirst)
{
cout << ","; //从第二个序列开始,在序列的前面加上英文逗号“,”
}
bFirst = false;
for (int k = i; k <= j; k++)
{
cout << k;
if (k != j)
{
cout << " "; //序列最后一个数字时,不用输出“ ”
}
}
bFlag = true;
break;
}
}
}
if (!bFlag)
{
cout << "NONE" << endl;
return 1;
}
cout << endl;
system("pause");
return 0;
}
输出的结果如图:
很遗憾,结果还是零分,一个测试也没通过。当时做到这里,确实有点急了,毕竟这是在面试,时间不等人啊。只能回头重新看题目了,到底是什么导致测试通不过呢?当我重新看到最后的样列输入时,突然想到既然输出可能有要求,那么输入是不是可能也有要求呢?于是我决定把中文提示去掉试试,下面是我提交的第三份代码:
#include <iostream>
using namespace std;
int main()
{
int nSplitNum = 0;
cin >> nSplitNum;
//判断合法性
if (nSplitNum < 1 || nSplitNum > 100)
{
cout << "ERROR" << endl;
return 1;
}
static bool bFirst = true;
bool bFlag = false; //记录是否有符合要求的序列
for (int i = 1; i <= nSplitNum / 2; i++)
{
int nSum = i;
for (int j = i + 1; j < nSplitNum; j++)
{
nSum += j;
if (nSum > nSplitNum)
{
break;
}
else if (nSum == nSplitNum)
{
if (!bFirst)
{
cout << ",";
}
bFirst = false;
//如果相等,循环输出序列
for (int k = i; k <= j; k++)
{
cout << k;
if (k != j)
{
cout << " "; //序列最后一个数字时,不用输出“ ”
}
}
bFlag = true;
break;
}
}
}
if (!bFlag)
{
cout << "NONE" << endl;
return 1;
}
cout << endl;
system("pause");
return 0;
}
输出结果如图:
至此,终于提示测试全部通过!不过,这却影响到了我的面试结果。。。。。。
简简单单的题目,在机考时却几经波折,可见在机考时,不仅要确保代码正确,还要严格按照给出的输入输出格式进行显示。在普通的笔试中,只要关键代码部分写对了,面试官一般就会认为你掌握相应的知识了,所以机考的难度明显要大于笔试的难度。同时机考时需要注意一些更加细节的地方,由于是机器判卷,只要稍有不合理其规则的地方,就会导致全部被判断出错,就比如我这里第二份代码中的“请输入一个大于0并且不大于100的整数”这样的一个提示,在平时的Win32程序编写中,加上这个提示会显得人性化一点,但是这道题里已经给出了样例输入,如果加了那么肯定就错了。因此,在机考时还要注意自己在平时的一些编程习惯是否和题目的要求相吻合。
相关文章推荐
- 将任意一个正整数n整数的立方分解为连续n个奇数之和
- 一个正整数分解为几个连续的正整数之和
- 一个正整数如何分解为几个连续的正整数之和的形式
- 输入一个正整数,若该数能用几个连续正整数之和表示,则输出所有可能的正整数序列
- 【IT面试题002】将一个正整数拆成几个连续整数之和
- 将一个正整数分解为多个连续整数之和
- 把任意一个正整数分解成几个素因子的幂的乘积
- 程序员面试题目总结--数组(五)【数组的后面m个数移动为前面m个数、列的前n项数据、判断整数x是否可以表示成n个连续正整数的和、数组中出现奇数次的元素、二维数组中的查找】
- 网易笔试题:输入一个正整数,若该数能用几个连续正整数之和表示,则输出所有可能的正整数序列。
- 网易笔试题:输入一个正整数,若该数能用几个连续正整数之和表示,则输出所有可能的正整数序列。
- 一个整数分解为连续正整数之和
- 经典题:一个整数分解为连续正整数之和
- 经典题:一个整数分解为连续正整数之和
- 输入一个正整数,若该数能用几个连续正整数之和表示,则输出所有可能的正整数序列。
- 编程题:输入一个正整数,若该数能用几个连续正整数之和表示,则输出所有可能的正整数序列
- 任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0。
- 陈利人 面试题 对于一个n位正整数a,去掉其中任意k(k<=n)个数字后,剩下的数字按原次序排列可以组成一个新的正整数。设计一个删数算法,使得剩下的数字组成的正整数最小。
- 判断一个整数x是否可以表示成n(n>=2)个连续正整数的和
- 一个有序正整数集S,若要保证整数集中所有的数通过组合(相加)可以表示1~N中任意一个正整数
- 给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数。