洛谷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 应输出为 de3-4 应输出为 34。如果减号右边的字符按照 ASCII 码的顺序小于或等于左边字符,输出时,要保留中间的减号,例如:d-d 应输出为 d-d3-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];
			}
		}
	}
}
posted @ 2022-08-12 15:43  JX_weak  阅读(86)  评论(0)    收藏  举报