p1109 【noip2007提高】字符串展开

版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/84920142

题目

描述 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;
}*/

猜你喜欢

转载自blog.csdn.net/huashuimu2003/article/details/84920142