洛谷P1098 [NOIP2007 提高组] 字符串的展开
Posted 江上舟摇
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷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的简便性和威力。
不多解释了,详细的注意事项和代码如下:
#include<bits/stdc++.h> using namespace std; int main() ios::sync_with_stdio(false);//快速输入输出流 int p1,p2,p3; string s; cin>>p1>>p2>>p3>>s; for(register int i=1;i<s.length()-1;i++) //从第二个元素到倒数第二的元素,其余的是负号就直接不用管了 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])))//超长判断 if(p1==1) s.erase(s.begin()+i);//删除负号 string a;//定一个空的字符串用来操作 for(register int k=s[i-1]+1;k<=s[i]-1;k++) //按ascii码顺序 char ch=k;//用来插入 for(register int j=1;j<=p2;j++) //插入p2个 a.push_back(ch);//插到空字符串的队尾 if(p3==2) reverse(a.begin(),a.end());//调换 s.insert(i,a);//把操作完成的字符串插到删除负号的地方 else if(p1==2) s.erase(s.begin()+i);//删除负号 string a;//定义一个空字符串来操作 for(register int k=s[i-1]+1;k<=s[i]-1;k++)//按ASCII码顺序 char ch=k;//用来插入的字符 ch=toupper(ch);//转大写 for(register int j=1;j<=p2;j++) a.push_back(ch);//同上 if(p3==2) reverse(a.begin(),a.end()); s.insert(i,a); else if(p1==3) s.erase(s.begin()+i); string a; for(register int k=s[i-1]+1;k<=s[i]-1;k++) for(register int j=1;j<=p2;j++) a.push_back(\'*\');//插入 “*” if(p3==2) reverse(a.begin(),a.end());//翻转 s.insert(i,a); cout<<s<<endl; return 0;
以上是关于洛谷P1098 [NOIP2007 提高组] 字符串的展开的主要内容,如果未能解决你的问题,请参考以下文章