41.题目描述
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
输出描述:
输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
思路:采用两个指针分别指向小数据的一端和大数据的一端,如果满足当前两个指针之间的数据之和等于sum,则找到一组满足要求的数据。如果当前的和大于sum则持续改进nSmall指导不满足条件,改进的过程中如果满足当前两个指针之间的数据之和等于sum,则找到一组满足要求的数据。否则nBig自加,nCurSum加上nBig。
注意:二维容器的使用,例如:vector<vector<int> > number,它是将vector<int>变量作为元素的一元容器。
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
vector<vector<int> > FindContinuousSequence(int sum) {
//如果sum小于3,这说明不存在这样的情况,输入不合法
if(sum< 3)
returnvector<vector<int> >(0, vector<int>(0));
vector<vector<int>> naResult;
vector<vector<int>>::iterator iteResult = naResult.begin();
intnSmall = 1;
intnBig = 2;
intnMid = (sum+1)/2;//当sum为2个数的和时,其最大的值为sum/2+1,最小值为sum/2;
intnCurSum = nSmall + nBig;
while(nSmall< nMid)
{
//当当前的nCurSum与sum相等时,则打印nSmall与nBig之间的数据
if(nCurSum== sum)
{
inti = nSmall;
/*vector<int>result(nBig - nSmall + 1);
vector<int>::iteratorite = result.begin();
for(; ite != result.end(); ite++)
{
*ite= i++;
}*/
//以上注释的部分也能实现数据的保存
vector<int>result;
for(;i <= nBig; i++)
result.push_back(i);
naResult.push_back(result);
}
//当当前的nCurSum大于sum时
while(nCurSum> sum && nSmall < nMid)
{
nCurSum-= nSmall;
nSmall++;
if(nCurSum== sum)
{
inti = nSmall;
/*vector<int>result(nBig - nSmall + 1);
vector<int>::iteratorite = result.begin();
for(; ite != result.end(); ite++)
{
*ite= i++;
}*/
//以上注释的部分也能实现数据的保存
vector<int>result;
for(;i <= nBig; i++)
result.push_back(i);
naResult.push_back(result);
}
}
nBig++;
nCurSum+= nBig;
}
returnnaResult;
}
};
int main()
{
Solutions;
vector<vector<int>> result = s.FindContinuousSequence(9);
vector<vector<int>>::iterator ite1 = result.begin();
vector<int>::iteratorite2 = ite1->begin();
for(ite1= result.begin(); ite1 != result.end(); ite1++)
{
for(ite2= ite1->begin(); ite2 != ite1->end(); ite2++)
{
cout<<*ite2<<"";
}
cout<<endl;
}
return0;
}
42.题目描述
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
输出描述:
对应每个测试案例,输出两个数,小的先输出。
思路:本题目与41题相似,只需要用两个指针,一个指针指向数组的最前面,另一个指针指向数组的最后面。将两指针分别向中间移动,当找到满足条件的第一个即为乘机最小,即可直接得到正确的答案。具体实现见代码:
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
vector<int> FindNumbersWithSum(vector<int> array,int sum) {
//如果数组元素个数少于2个则返回空
if(array.size()< 2)
returnvector<int>(0);
vector<int>::iteratoriteSmall = array.begin();
vector<int>::iteratoriteBig = array.end()-1;
intnCurSum = *iteBig + *iteSmall;
while(iteSmall< iteBig)
{
if(nCurSum== sum)
{
vector<int>result;
result.push_back(*iteSmall);
result.push_back(*iteBig);
returnresult;
}
while(iteSmall< iteBig && nCurSum > sum)
{
iteBig--;
nCurSum= *iteSmall + *iteBig;
if(nCurSum== sum)
{
vector<int>result;
result.push_back(*iteSmall);
result.push_back(*iteBig);
returnresult;
}
}
iteSmall++;
nCurSum= *iteSmall + *iteBig;
}
returnvector<int>(0);
}
};
int main()
{
freopen("data.txt","r", stdin);
vector<int>array(12);
vector<int>::iteratorite = array.begin();
for(;ite != array.end(); ite++)
cin>>*ite;
Solutions;
vector<int>result = s.FindNumbersWithSum(array, 12);
ite= result.begin();
for(;ite != result.end(); ite++)
cout<<*ite<<"";
cout<<endl;
return0;
}
43.题目描述
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!
思路:1.先整体旋转字符转
2.旋转前一部分字符串
3.旋转后一部分字符串
#include <iostream>
#include <string>
using namespace std;
class Solution {
public:
string LeftRotateString(string str, int n) {
//如果str为NULL则返回空串,若n>字符串的长度,也返回空串
intlen = str.size();
cout<<len<<endl;
if(len<= 0 || len < n)
return"";
//整体旋转
intnHead = 0;
intnTail = len-1;
while(nHead< nTail)
{
charch = str[nHead];
str[nHead]= str[nTail];
str[nTail]= ch;
nHead++;
nTail--;
}
//前部分旋转
nHead= 0;
nTail= len-n-1;
while(nHead< nTail)
{
charch = str[nHead];
str[nHead]= str[nTail];
str[nTail]= ch;
nHead++;
nTail--;
}
//后部分旋转
nHead= len-n;
nTail= len-1;
while(nHead< nTail)
{
charch = str[nHead];
str[nHead]= str[nTail];
str[nTail]= ch;
nHead++;
nTail--;
}
returnstr;
}
};
int main()
{
stringstr1 = "abcXYZdef";
cout<<str1<<endl;
Solutions;
stringstr = s.LeftRotateString(str1, 3);
cout<<str<<endl;
return0;
}
44.题目描述
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
思路:1.将字符串整体翻转
2.以空格或者’\0’为分割,将被分割 字符串进行翻转
class Solution {
public:
string ReverseSentence(string str) {
//如果字符串为空,则返回空字符串
if(str.size()<= 0)
return"";
if(str.size()== 1)
returnstr;
//整体翻转字符串
intend = str.size()-1;
intstart = 0;
while(start< end)
{
charch = str[start];
str[start]= str[end];
str[end]= ch;
start++;
end--;
}
//将以空格为分割的字符串进行翻转
intnAhead = 0;
intnTail = 0;
while(str[nAhead]!= '\0')
{
if(str[nAhead]== ' ')
{
nAhead++;
nTail++;
}
elseif(str[nTail] == ' ' || str[nTail] == '\0')
{
intnahead = nAhead;
intntail = --nTail;
while(nahead< ntail)
{
charch = str[nahead];
str[nahead]= str[ntail];
str[ntail]= ch;
nahead++;
ntail--;
}
nAhead= ++nTail;
}
else
nTail++;
}
returnstr;
}
};
45.题目描述
LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子.....LL不高兴了,他想了想,决定大\小王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何。为了方便起见,你可以认为大小王是0。
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
bool IsContinuous( vector<int> numbers ) {
//如果数组的元素个数不是5,则返回false
if(numbers.size()!= 5)
returnfalse;
//对数进行排序
for(inti = 0; i < numbers.size(); i++)
{
for(intj = i; j < numbers.size(); j++)
{
if(numbers[i]> numbers[j])
{
inttemp = numbers[i];
numbers[i]= numbers[j];
numbers[j]= temp;
}
}
}
//统计0的个数
intnNumOfZero = 0;
vector<int>::iteratorite = numbers.begin();
for(;ite != numbers.end() && *ite == 0; ite++)
nNumOfZero++;
cout<<nNumOfZero<<endl;
//统计数之间的间隔数
intnNumGap = 0;
vector<int>::iteratoriteFirst = numbers.begin();
vector<int>::iteratoriteSecond = iteFirst+1;
while(iteSecond!= numbers.end())
{
if(nNumOfZero== 4)
returntrue;
while(*iteFirst== 0 && iteSecond != numbers.end())
{
iteFirst= iteSecond++;
}
if(*iteFirst== *iteSecond && *iteFirst != 0 && *iteSecond != 0)
returnfalse;
nNumGap+= (*iteSecond) - (*iteFirst) - 1;
iteFirst= iteSecond++;
}
cout<<nNumGap<<endl;
if(nNumGap> nNumOfZero)
returnfalse;
else
returntrue;
}
};
int main()
{
vector<int>array(5);
vector<int>::iteratorite = array.begin();
for(;ite != array.end(); ite++)
{
cout<<"Pleaseinput num:";
cin>>*ite;
}
Solutions;
if(s.IsContinuous(array))
cout<<"Goodlucky!"<<endl;
else
cout<<"Badlucky!"<<endl;
return0;
}