一、reverse() 用法简述
reverse()会将区间[beg,end)内的元素全部逆序。
注意:第二个参数是数组最后一个元素的下一个地址。
核心代码:
string s;
int n=s.length();
/*将全部string元素逆序*/
reverse(s.begin(),s.end());
/*将部分元素逆序,如下示例为区间[i,j]*/
reverse(s.begin()+i,s.begin()+j+1);
二、reverse() 应用
1.字符串变形
题目描述:
对于一个给定的字符串,我们需要在线性(也就是O(n))的时间里对它做一些变形。首先这个字符串中包含着一些空格,就像"Hello World"一样,然后我们要做的是把着个字符串中由空格隔开的单词反序,同时反转每个字符的大小写。比如"Hello World"变形后就变成了"wORLD hELLO"。
大致思路:
将全部字符翻转,这样就可以实现把由空格隔开的单词在位置上的反序,进而下一步将每个单词内部再次翻转。这样一来,实现将单词的位置反序,并恢复了每个单词的正常字母顺序。
核心代码:
string trans(string s, int n) {
reverse(s.begin(),s.end());
for(int i=0;i<n;i++){
int j=i;
while(j<n&&s[j]!=' '){
j++;
}
reverse(s.begin()+i,s.begin()+j);
i=j;
}
string ans;
for(int i=0;i<n;i++){
if(s[i]==' '){
ans+=s[i];
}
else if(s[i]>='A'&&s[i]<='Z'){
ans+=s[i]+32;
}
else{
ans+=s[i]-32;
}
}
return ans;
}
2.进制转换
题目描述
给定一个十进制数M,以及需要转换的进制数N。将十进制数M转化为N进制数。(M是32位整数,2<=N<=16)
核心代码:
string solve(int M, int N) {
string s="0123456789ABCDEF";
string ans="";
int flag=1;
if(M==0){
return "0";
}
else if(M<0){
M=-M;
flag=0;
}
while(M){
ans+=s[M%N];
M/=N;
}
if(flag==0){
ans+="-";
}
/*记得翻转*/
reverse(ans.begin(),ans.end());
return ans;
}
另:cf
A. Wizard of Orz(链接: link.)
题目描述:
n块板上同时出相同的数字(0-9),都以一秒改变一个状态的频率变化。0的下一个状态是1,1的下一个状态是2……9的下一个状态是0。任意选中一块板(x),使其停止计数,则距 x 的距离为 |x-y| 的板 y 停止计数的时间比 x 晚 |x-y| 秒。在全部板都停止计数后从左至右写下每个板的数字,输出最大数。
大致思路:
板的个数是确定的,因此,所要输出的数的位数是一定的,那么要想得到的数最大,最高位应为 9,根据板变化的规律,显然相邻板的数字是不可能相同的,因此最高位的下一位为 0 或 8,显然为 8 时会使数尽可能大。那么因为我们暂时还不知道是先暂停哪一块板,所以 8 的下一位可能是 7 也可能是 9,显然,我们选择 9。分析至此,前三块板的数字已确定好,“989”。不难看出,是先暂停第二块板 8,它的前一块板和后一块板和它距离为 1,晚停止计数一秒。既然确定好了先暂停哪块板,剩余位置的板按规律填上数字即可。
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--){
int n;
cin>>n;
if(n==1){
cout<<"9"<<endl;;
}
else if(n==2){
cout<<"98"<<endl;
}
else if(n==3){
cout<<"989"<<endl;
}
else{
cout<<"989";
int p=0;
for(int i=0;i<n-3;i++){
cout<<p;
p++;
if(p==10){
p=0;
}
}
cout<<endl;
}
}
return 0;
}