洛谷P1098 字符串的展开(NOIP 2007 T2)题解
\(Luogu P1098\) 字符串的展开 题解
原题大意:给\(3\)个参数\(p_1,p_2,p_3\)和\(1\)个字符串\(s\),当\(s\)中出现字符-的时候,且这个符号的两边需同时为小写字母或者数字时要进行展开操作。展开是根据参数\(p_1,p_2,p_3\)确定的,具体规则是:
参数 \(p_1\):展开方式。\(p_1=1\) 时,对于字母子串,填充小写字母;\(p_1=2\) 时,对于字母子串,填充大写字母。这两种情况下数字子串的填充方式相同。\(p_1=3\) 时,不论是字母子串还是数字字串,都用与要填充的字母个数相同的星号 * 来填充。
参数 \(p_2\):填充字符的重复个数。\(p_2=k\) 表示同一个字符要连续填充 \(k\) 个。例如,当 \(p_2=3\) 时,子串d-h 应扩展为 deeefffgggh。减号两边的字符不变。
参数 \(p_3\):是否改为逆序:\(p_3=1\) 表示维持原来顺序,\(p_3=2\) 表示采用逆序输出,注意这时候仍然不包括减号两端的字符。例如当 \(p_1=1\)、\(p_2=2\)、\(p_3=2\) 时,子串 d-h 应扩展为 dggffeeh。
如果减号右边的字符恰好是左边字符的后继,只删除中间的减号,例如:d-e 应输出为 de,3-4 应输出为 34。如果减号右边的字符按照 ASCII 码的顺序小于或等于左边字符,输出时,要保留中间的减号,例如:d-d 应输出为 d-d,3-1 应输出为 3-1。
看完了题目,我们进行分析:这不就是一道模拟题嘛。
刚开始做这道题我的内心\(os\):就这!
其实这道题有蛮多的细节。
题意很好理解,代码很快就能调出来,关键是这些细节的处理问题(其实细节的处理很简单,关键是不好发现这些细节)。
1.第一个字符是-
这个直接特判。
2.两个-连在一起
这个也是特判。
3.一个-两侧分别是数字和字母
这个其实是我读题不太仔细,就漏了这个细节。
4.多输出/少数出的问题
这个多加调试就行了。
毕竟是一道黄题
有这么多细节也足够是\(NOIP \ 2007 \ T2\)了
然后是\(Code\)(为了打的时候方便就把码量翻了倍了):
#include<bits/stdc++.h>
using namespace std;
const int MAXN=2e6+10;
int p1,p2,p3;
string s;
int len;
char c[MAXN];
char C[MAXN];
int num;
char cc='a';
bool check(int x){
if(s[x-1]>='a'&&s[x-1]<='z'&&s[x+1]>='0'&&s[x+1]<='9'){
return true;
}else if(s[x-1]>='0'&&s[x-1]<='9'&&s[x+1]>='a'&&s[x+1]<='z'){
return true;
}
return false;
}
signed main() {
cin>>p1>>p2>>p3;
cin>>s;
len=s.length()-1;
for(int i=1; i<=26; i++) {
c[i]=cc;
cc++;
}
cc='A';
for(int i=1; i<=26; i++) {
C[i]=cc;
cc++;
}
if(p3==1) {
for(int i=0; i<=len; i++) {
if(s[i]=='-') {
if(s[i-1]>=s[i+1]) {
cout<<"-";
continue;
}else if(check(i)||i==0||s[i]==s[i-1]||s[i]==s[i+1]){
cout<<"-";
continue;
}else {
if(s[i-1]>='a'&&s[i+1]<='z') {
num=s[i-1]-'a'+2;
if(p1==1) {
for(int j=s[i-1]-'a'+1; j<=s[i+1]-'a'-1; j++) {
for(int k=1; k<=p2; k++) {
cout<<c[num];
}
num++;
}
} else if(p1==2) {
for(int j=s[i-1]-'a'+1; j<=s[i+1]-'a'-1; j++) {
for(int k=1; k<=p2; k++) {
cout<<C[num];
}
num++;
}
} else if(p1==3) {
for(int j=s[i-1]-'a'+1; j<=s[i+1]-'a'-1; j++) {
for(int k=1; k<=p2; k++) {
cout<<"*";
}
}
}
} else if(s[i-1]>='0'&&s[i+1]<='9') {
num=s[i-1]-'0'+1;
if(p1!=3) {
for(int j=s[i-1]-'0'+1; j<=s[i+1]-'0'-1; j++) {
for(int k=1; k<=p2; k++) {
cout<<num;
}
num++;
}
} else {
for(int j=s[i-1]-'0'+1; j<=s[i+1]-'0'-1; j++) {
for(int k=1; k<=p2; k++) {
cout<<"*";
}
}
}
}
}
}else{
cout<<s[i];
}
}
} else {
for(int i=0; i<=len; i++) {
if(s[i]=='-') {
if(s[i-1]>=s[i+1]||check(i)||i==0||s[i]==s[i-1]||s[i]==s[i+1]) {
cout<<"-";
continue;
} else {
if(s[i-1]>='a'&&s[i+1]<='z') {
num=s[i+1]-'a';
if(p1==1) {
for(int j=s[i-1]-'a'+1; j<=s[i+1]-'a'-1; j++) {
for(int k=1; k<=p2; k++) {
cout<<c[num];
}
num--;
}
} else if(p1==2) {
for(int j=s[i-1]-'a'+1; j<=s[i+1]-'a'-1; j++) {
for(int k=1; k<=p2; k++) {
cout<<C[num];
}
num--;
}
} else if(p1==3) {
for(int j=s[i-1]-'a'+1; j<=s[i+1]-'a'-1; j++) {
for(int k=1; k<=p2; k++) {
cout<<"*";
}
}
}
} else if(s[i-1]>='0'&&s[i+1]<='9') {
num=s[i+1]-'0'-1;
if(p1!=3) {
for(int j=s[i-1]-'0'+1; j<=s[i+1]-'0'-1; j++) {
for(int k=1; k<=p2; k++) {
cout<<num;
}
num--;
}
} else {
for(int j=s[i-1]-'0'+1; j<=s[i+1]-'0'-1; j++) {
for(int k=1; k<=p2; k++) {
cout<<"*";
}
}
}
}
}
}else{
cout<<s[i];
}
}
}
}
-------------------------------------------
个性签名:そんなに形に拘らないの、大切なのは心よ
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!

浙公网安备 33010602011771号