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

博客 分享
0 246
张三
张三 2022-02-12 16:55:16
悬赏:0 积分 收藏

洛谷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 江上舟摇 阅读(0) 评论(0) 编辑 收藏 举报
回帖
    张三

    张三 (王者 段位)

    821 积分 (2)粉丝 (41)源码

     

    温馨提示

    亦奇源码

    最新会员