1.求子数组的最大和
例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,因此输出为该子数组的和18。
因为是O(N)的复杂度,因此需采用的DP的思想,记录下当前元素之和(为其最优状态,既最大),将其与目前所得的最大和比较,若大于则更新,否则继续。状态的累加遵循这个过程:如果当前和小于0,则放弃该状态,将其归零。
//求子数组的最大和
//利用的是dp的思想,依次遍历数组中的每个元素,把他们相加,如果加起来小于0,则
//把当前元素之和清为0,否则则和最大和比较,更新最大和,最后得到必是子数组的最大和
#include<iostream>
using namespace std;
int findGreatestSubSum(const int a[],const int size){
int curSum=0;
int maxSum=0;
for(int i=0;i<size;i++){
curSum+=a[i];
if(curSum<0) curSum=0; //放弃这个阶段,从新开始
if(curSum>maxSum) maxSum=curSum; //更新最大和
}
if(maxSum==0){ //若是数组中的元素均为负数,则输出里面的最大元素
maxSum=a[0]; //当然这步也可以写到上面一个循环里
for(int i=1;i<size;i++){
if(maxSum<a[i]) maxSum=a[i];
}
}
return maxSum;
}
int main(void){
int a[10]={1, -2, 3, 10, -4, 7, 2, -5};
cout<<findGreatestSubSum(a,10)<<endl;
system("pause");
return 0;
}
2.你让一些人为你工作了七天,你要用一根金条作为报酬。金条被分成七小块,每天给出一块。
如果你只能将金条切割两次,你怎样分给这些工人?
把金条分成三段(就是分两次,或者切两刀),分别是整根金条的1/7、2/7 4/7 第一天:给1/7的, 第二天:给2/7的,收回1/7的 第三天,给1/7的 第四天:给4/7的,收回1/7和2/7的 第五天:给1/7的 第六天:给2/7的,收回1/7的
第3题
翻转句子中单词的顺序。
题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。
句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。
例如输入“I am a student.”,则输出“student. a am I”。
/*
第 3 题(字符串)
翻转句子中单词的顺序。
题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。
句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。
例如输入“I am a student.”,则输出“student. a am I”。
start time 15:12
end time 15:39
*/
#include <iostream>
#include <vector>
using namespace std;
typedef struct Words{
int len;
char * start;
}Words;
void reverseSentence(char * c)
{
vector<Words> S; //存储单词的栈
Words w;
w.start = c;
w.len = 0;
for (int i = 0; c[i] != ‘\0‘; i++)
{
if (c[i] != ‘ ‘)
{
w.len++;
}
else
{
if (w.len != 0)
{
S.push_back(w);
w.start = c + i + 1;
w.len = 0;
}
else //跳过多余的空格
{
w.start = c + i + 1;
}
}
}
if (w.len != 0) //压入最后一个词
{
S.push_back(w);
}
while (!S.empty())
{
Words w = S.back();
for (int i = 0; i < w.len; i++)
{
cout << *(w.start + i);
}
cout << ‘ ‘;
S.pop_back();
}
cout << endl;
}
int main()
{
char * c = " I am a student.";
reverseSentence(c);
return 0;
}
4:求1+2+…+n,
要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。
分析:这题本来很简单,但是不能用循环和条件判断语句。但是理论上所有的递归都可以转化为循环,那是否可以用递归代替循环呢?照着这个思路走下去,貌似可以。可是用递归的话,递归怎么终止呢?这就得在return语句中做文章了。最让人奔溃的是不让用乘除法。但是乘法本质上是加法的累加。
思路:
- 把循环化为递归。
- 乘法改为递归实现的累加。
- 递归的终止靠return语句做文章。
我最终的答案如下(包括测试程序):
- #include <stdio.h>
- int sum = 0;
- _Bool summation(int n)
- {
- sum += n;
- return n-1 && summation(n-1);
- }
- int main()
- {
- int n;
- scanf("%d",&n);
- summation(n);
- printf("%d\n",sum);
- return 0;
- }