洛谷P1098 [NOIP2007 提高组] 字符串的展开

题目链接:https://www.luogu.com.cn/problem/P1098

这个题出的真的很有质量,这个是我见过算是复杂的模拟题了,对付这种题,一丝都不能马虎,要想实现快捷而又简便的代码设计,并且针对于这个题繁琐的各种变量,我们采取STL大法,全局都采取STL大法的题目真的是不多,但这个题真的很值得。

我们必须要熟悉STL库的顺序式容器和关联式容器的STL表述方法,并且熟练应用,STL函数库的熟练应用是每个ACMer和OLer的必备技能,惭愧的是,我现在还没能完全掌握STL库,只能应用一部分,相信在日后的学习中STL的使用会越来越熟练。

我们简单介绍几个STL库:

#include<cctype>

加入这个头文件就可以调用以下函数:

1、isalpha(x) 判断x是否为字母

2、isdigit(x) 判断x是否为数字

3、islower(x) 判断x是否为小写字母

4、isupper(x) 判断x是否为大写字母

5、isalnum(x) 判断x是否为字母或数字

6、ispunct(x) 判断x是否为标点符号

7、isspace(x) 判断x是否为空格

对于以上函数,如果x符合条件的话,均会返回true,否则返回false

还有以下函数:

1、toupper(x) 如果x是小写字母,将其转换成大写字母

2、tolower(x) 如果x是大写字母,将其转换成小写字母

 

#include<string>

在本题目中用到的有以下几个函数,也是此头文件下比较常用的函数,更多的可以百度以下

1、s.erase(x,y) 表示将字符串s从x位置起删除y个字符

2、s.insert(x,y) 表示将字符串y(或字符y)插入到s的x位置处

3、s.push_back(x) 表示在s的末尾插入字符x

4、reverse(s.begin(),s.end()) 将字符串s翻转

还有数组vector,其实数组的操作和上述的几个差不多,stack栈的使用,queue,list,set,map,deque,multimap.....等等诸多STL的容器以及例如next_permutation,sort等诸多STL函数的使用。

这个题充分使用了STL库并且将容器的作用发挥到极致。

在此中,为了实现cin,cout输入输出流的快速使用以达到节省时间的目的,我们应用了快速输入输出流:ios::sync_with_stdio(false),这样我们就可以随心所欲的使用cin与cout,不用在担心时间的浪费问题。

还有一个细节要注意的是,大量的使用for循环可能复杂度会大大的增加,我们在此使用register定义变量流来获取时间的一种节约,使用register修饰的变量可以提高它的读写速度,一般用于多层循环中。

这个题细节太多了,学到的知识也太多了,不得不说,这个题很有质量,我在此中收获了不少,也再次见证了STL的简便性和威力。

不多解释了,详细的注意事项和代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     ios::sync_with_stdio(false);//快速输入输出流 
 5     int p1,p2,p3;
 6     string s;
 7     cin>>p1>>p2>>p3>>s;
 8     for(register int i=1;i<s.length()-1;i++){    
 9     //从第二个元素到倒数第二的元素,其余的是负号就直接不用管了                                     
10         if(s[i]=='-'&&((islower(s[i-1])&&islower(s[i+1])&&s[i-1]<s[i+1])||(isdigit(s[i-1])&&isdigit(s[i+1])&&s[i-1]<s[i+1])))//超长判断 
11         {                                                                                     
12             if(p1==1){
13                 s.erase(s.begin()+i);//删除负号 
14                 string a;//定一个空的字符串用来操作 
15                 for(register int k=s[i-1]+1;k<=s[i]-1;k++)
16                 {//按ascii码顺序 
17                     char ch=k;//用来插入 
18                     for(register int j=1;j<=p2;j++) //插入p2个 
19                     a.push_back(ch);//插到空字符串的队尾 
20                 }
21                 if(p3==2) 
22                 reverse(a.begin(),a.end());//调换 
23                 s.insert(i,a);//把操作完成的字符串插到删除负号的地方 
24             }
25             else if(p1==2){
26                 s.erase(s.begin()+i);//删除负号 
27                 string a;//定义一个空字符串来操作 
28                 for(register int k=s[i-1]+1;k<=s[i]-1;k++)//按ASCII码顺序 
29                 {
30                     char ch=k;//用来插入的字符 
31                     ch=toupper(ch);//转大写 
32                     for(register int j=1;j<=p2;j++) 
33                     a.push_back(ch);//同上 
34                 }
35                 if(p3==2) 
36                 reverse(a.begin(),a.end());
37                 s.insert(i,a);
38             }
39             else if(p1==3){
40                 s.erase(s.begin()+i);
41                 string a;
42                 for(register int k=s[i-1]+1;k<=s[i]-1;k++)
43                     for(register int j=1;j<=p2;j++) 
44                     a.push_back('*');//插入 “*” 
45                 if(p3==2) 
46                 reverse(a.begin(),a.end());//翻转 
47                 s.insert(i,a);
48             }
49         }
50     }
51     cout<<s<<endl;
52     return 0;
53 }

 

posted @ 2022-02-12 16:44  江上舟摇  阅读(319)  评论(0编辑  收藏  举报