目录
排序子序列
题目描述
牛牛定义排序子序列为一个数组中一段连续的子序列,并且这段子序列是非递增或者非递减排序的。牛牛有一个长度为n的整数数组A,他现在有一个任务是把数组A分为若干段排序子序列,牛牛想知道他最少可以把这个数组分为几段排序子序列.
如样例所示,牛牛可以把数组A划分为[1,2,3]和[2,2,1]两个排序子序列,至少需要划分为2个排序子序列,所以输出2
输入描述:输入的第一行为一个正整数n(1 ≤ n ≤ 10^5), 第二行包括n个整数A_i(1 ≤ A_i ≤ 10^9),表示数组A的每个数字。
输出描述:输出一个整数表示牛牛可以将A最少划分为多少段排序子序列
解题思路:
由题目可知我们要把原来一段序列分为非递增和非递减两种形式的子序列,所以我们要明白非递增和非递减是什么意思?递增:a[i]<a[i+1],顾名思义递增时i项小于i+1项,所以非递增就是a[i]>=a[i=1];递减:a[i]>a[i+1],所以非递减:a[i]<=a[i+1]。
1、我们要知道这道题要遍历数组,一次比较各个子序列,所以我们设置一个count来记录每次变换,从而记录下来子序列的个数。
2、当a[i]>a[i+1]时,此时为非递增序列,所以我们一直遍历到下一个值不大于等于为止,然后count++,然后到下一位进行判断。
3、当a[i]<a[i+1]时,此时为非递减序列,所以我们一直遍历到下一个值不小于等于为止,然后count++,然后到下一位进行判断。
4、当a[i]==a[i+1]时,此时i++就好,进行下一位的判断,因为此时属于非递增也属于非递减。
代码
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int n;
cin>>n;
vector<int> v;
v.resize(n+1);//大小设置为n+1避免我们遍历时数组越界
for(int i=0;i<v.size();i++)
{
cin>>v[i];
}
int i=0;
int count=0;
while(i<n)
{
if(v[i]<v[i+1])
{
while(i<n && v[i]<=v[i+1])
{
i++;
}
count++;
i++;
}
if(v[i]==v[i+1])
{
i++;
}
if(v[i]>v[i+1])
{
while(i<n && v[i]>=v[i+1])
{
i++;
}
count++;
i++;
}
}
cout<<count<<endl;
return 0;
}
倒置字符串
题目描述
将一句话的单词进行倒置,标点不倒置。比如 I like beijing. 经过函数后变为:beijing. like I
解题思路:
首先我们要知道空格是一个单词的结束符,然后首先将单词本身逆置,然后全部逆置。
代码
#include<iostream>
#include<string>
using namespace std;
void reverse(string& str,int begin,int end){
while(begin<end)
{
std::swap(str[begin],str[end]);
begin++;
end--;
}
}
int main()
{
string str;
getline(cin,str);
int j=0;//记录一开始要逆置的位置
for(int i=0;i<=str.size();i++)//
{
if(str[i]==' ' || str[i]=='\0')
{
reverse(str,j,i-1);//先逆置每个单词
j=i+1;
}
}
reverse(str,0,str.size()-1);//最后全部逆置
cout<<str<<endl;
return 0;
}