题目
描述 Description
在初赛普及组的“阅读程序写结果”的问题中,我们曾给出一个字符串展开的例子:如果在输入的字符串中,含有类似于“d-h”或“4-8”的子串,我们就把它当作一种简写,输出时,用连续递增的字母或数字串替代其中的减号,即,将上面两个子串分别输出为“defgh”和“45678”。在本题中,我们通过增加一些参数的设置,使字符串的展开更为灵活。具体约定如下:
(1)遇到下面的情况需要做字符串的展开:在输入的字符串中,出现了减号“-”,减号两侧同为小写字母或同为数字,且按照ASCII码的顺序,减号右边的字符严格大于左边的字符。
(2)参数p1:展开方式。p1=1时,对于字母子串,填充小写字母;p1=2时,对于字母子串,填充大写字母。这两种情况下数字子串的填充方式相同。p1=3时,不论是字母子串还是数字子串,都用与要填充的字母个数相同的星号“*”来填充。
(3)参数p2:填充字符的重复个数。p2=k表示同一个字符要连续填充k个。例如,当p2=3时,子串“d-h”应扩展为“deeefffgggh”。减号两侧的字符不变。
(4)参数p3:是否改为逆序:p3=1表示维持原有顺序,p3=2表示采用逆序输出,注意这时仍然不包括减号两端的字符。例如当p1=1、p2=2、p3=2时,子串“d-h”应扩展为“dggffeeh”。
(5)如果减号右边的字符恰好是左边字符的后继,只删除中间的减号,例如:“d-e”应输出为“de”,“3-4”应输出为“34”。如果减号右边的字符按照ASCII码的顺序小于或等于左边字符,输出时,要保留中间的减号,例如:“d-d”应输出为“d-d”,“3-1”应输出为“3-1”。
输入格式 Input Format
输入文件expand.in包括两行:
第1行为用空格隔开的3个正整数,依次表示参数p1,p2,p3。
第2行为一行字符串,仅由数字、小写字母和减号“-”组成。行首和行末均无空格。
输出格式 Output Format
输出文件expand.out只有一行,为展开后的字符串。
样例输入 Sample Input
一共三组样例。
1 2 1
abcs-w1234-9s-4zz
2 3 2
a-d-d
3 4 2
di-jkstra2-6
样例输出 Sample Output
abcsttuuvvw1234556677889s-4zz
aCCCBBBd-d
dijkstra2************6
时间限制 Time Limitation
1s
来源 Source
noip2007提高组第二题
40%的数据满足:字符串长度不超过5
100%的数据满足:1<=p1<=3, 1<=p2<=8, 1<=p3<=2。字符串长度不超过100
代码
#include<bits/stdc++.h>
using namespace std;
char a[1100000],r[1100000];//r存放结果字符串
int len,l,d,e,f,cnt=0;//l需填充的字符串长度
int main() {
int p1,p2,p3,tmp;
scanf("%d %d %d %s",&p1,&p2,&p3,&a);//&号别忘写.
len=strlen(a);//只能用在char数组上.
for (int i=0; i<len; i++) {
d=a[i-1]; e=a[i]; f=a[i+1];//不是减号,减号两侧是字母和数字,减号左边大于减号右边或等于右边
if (e!='-'||!((d>='0'&&f<='9')||(d>='a'&&f<='z'))) r[cnt++]=e;//不等于‘-’或不在规定范围内
else if (f-d>25) r[cnt++]=e;//若差值大于25,则必定是一个数字一个字母,因为字母一共26个,
else if (d>=f) r[cnt++]=e;//若左侧大于右侧或左侧等于右侧 最大差值25。
else if (f-d==1) {//如果左侧和右侧是连续的
for (int j=i; j<len; j++) {
if (e=='-') continue;//a[i]如果不判断是不是'-',输出就会神奇的多一个'-'
else r[cnt++]=e;
}
} else {
l=f-d;
if (p1==2&&d>='a'&&f<='z') tmp=d-32+1;//大写存入
else if (p1==2&&d>='0'&&f<='z') tmp=d+1;//p1=2时如果是数字,仍然按原方式存入,
else if (p1==1) tmp=d+1; //这是必须特判的,不然会炸。
else if (p1==3) tmp='*';
if (tmp=='*') {
for (int j=1; j<l; j++)
for (int k=0; k<p2; k++)
r[cnt++]=tmp;
} else {
if (p3==1) {
for (int j=1; j<l; j++) {
for (int k=0; k<p2; k++)
r[cnt++]=tmp;
tmp++;
}
} else if (p3==2) {//逆序输出
tmp+=l-2;//eg:a-e,p3==1时,tmp=b,现在p3==2了,那么tmp就等于d.
for (int j=1; j<l; j++) {
for (int k=0; k<p2; k++)
r[cnt++]=tmp;
tmp--;
}
}
}
}
}
printf("%s",r);
return 0;
}
/*WA
#include<bits/stdc++.h>
using namespace std;
char str[10000];
int p1,p2,p3,j,d,e,f,g;
void c() {
g=j;
for (int k=1; k<=p2; k++)
printf("%c",g);
}
void print() {
if (p3==1)
for (j=e; j<f; j++)
c();
else if (p3==2)
for (j=f-1; j>e; j--)
c();
}
int main() {
scanf("%d %d %d %s",&p1,&p2,&p3,&str);
for (int i=0; str[i]; i++) {
d=str[i-1];
e=str[i];
f=str[i+1];
if (e=='-'&&d<f&&((d>='0'&&f<='9')||(d>='a'&&f<='z'))) {
if (d+1==f) {
e=f;
for (int k=i; str[k]; k++) {
str[k]=str[k+1];
printf("%c",str[k]);
}
} else {
if (p1==1) {
e=d+1;
print();
} else if (p1==2) {
if (d>='a'&&f<='z') e=d+1-32;
else e=d+1;
print();
} else {
e='*';
print();
}
}
} else printf("%c",e);
}
return 0;
}*/