洛谷P1098 [NOIP2007 提高組] 字符串的展開
題目鏈接://www.luogu.com.cn/problem/P1098
這個題出的真的很有質量,這個是我見過算是複雜的模擬題了,對付這種題,一絲都不能馬虎,要想實現快捷而又簡便的代碼設計,並且針對於這個題繁瑣的各種變量,我們採取STL大法,全局都採取STL大法的題目真的是不多,但這個題真的很值得。
我們必須要熟悉STL庫的順序式容器和關聯式容器的STL表述方法,並且熟練應用,STL函數庫的熟練應用是每個ACMer和OLer的必備技能,慚愧的是,我現在還沒能完全掌握STL庫,只能應用一部分,相信在日後的學習中STL的使用會越來越熟練。
我們簡單介紹幾個STL庫:
加入這個頭文件就可以調用以下函數:
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是大寫字母,將其轉換成小寫字母
在本題目中用到的有以下幾個函數,也是此頭文件下比較常用的函數,更多的可以百度以下
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 }