逐个处理连字符,仅对合法同类递增区间按三个参数生成展开内容。
OJ: noi_openjudge
题目 ID: ch0107-35
难度:普及/提高-
标签:字符串模拟分类讨论python
日期: 2026-07-30 23:01
题意
根据
思路
扫描到连字符时,先判断两侧是否同类且严格递增;不合法则保留 -。合法时枚举两端之间的字符,按 p1 改写、按 p2 重复,再按 p3 决定是否整体逆序。两端字符由普通扫描自然保留。
代码
cpp
/*-----------------
* author: Rainboy
* email: rainboylvx@qq.com
* time: 2019年 07月 22日 星期一 12:24:19 GMT
* problem: luogu-P1098
*----------------*/
#include <bits/stdc++.h>
using namespace std;
int p1,p2,p3;
char str[1000];
char tmp[500];
int idx = 0;
int main(){
scanf("%d%d%d",&p1,&p2,&p3);
scanf("%s",str+1);
int len = strlen(str+1);
int i,j,k;
for (i=1;i<=len;i++){
char c = str[i];
if(c == '-'){
if(!((str[i-1] >='a' && str[i+1]<='z') || (str[i-1] >='0' && str[i+1]<='9')) ){
printf("-");
continue;
}
if( str[i-1] >= str[i+1]){
printf("%c",c);
}
else if( str[i-1] +1 == str[i+1])
continue;
else {
idx = 0;
memset(tmp,0,sizeof(tmp));
for(j=str[i-1]+1 ;j<str[i+1];j++){
for (k=1;k<=p2;k++){
if( p1 == 1)
tmp[idx++] = tolower(j);
else if( p1 == 2)
tmp[idx++] = toupper(j);
else
tmp[idx++] = '*';
}
}
if( p3 == 1) {
printf("%s",tmp);
} else {
int l = strlen(tmp);
for(k=l-1;k>=0;k--){
printf("%c",tmp[k]);
}
}
}
}
else
printf("%c",c);
}
return 0;
}复杂度
总结
Python代码
python
mode, repeat_count, direction = map(int, input().split())
text = input().strip()
answer = []
for index, character in enumerate(text):
if character != "-" or index == 0 or index == len(text) - 1:
answer.append(character)
continue
left, right = text[index - 1], text[index + 1]
same_kind = (left.islower() and right.islower()) or (left.isdigit() and right.isdigit())
if not same_kind or left >= right:
answer.append("-")
continue
middle = []
for code in range(ord(left) + 1, ord(right)):
character_to_fill = chr(code)
if mode == 2:
character_to_fill = character_to_fill.upper()
elif mode == 3:
character_to_fill = "*"
middle.append(character_to_fill * repeat_count)
expanded = "".join(middle)
answer.append(expanded if direction == 1 else expanded[::-1])
print("".join(answer))C++代码
cpp
/*-----------------
* author: Rainboy
* email: rainboylvx@qq.com
* time: 2019年 07月 22日 星期一 12:24:19 GMT
* problem: luogu-P1098
*----------------*/
#include <bits/stdc++.h>
using namespace std;
int p1,p2,p3;
char str[1000];
char tmp[500];
int idx = 0;
int main(){
scanf("%d%d%d",&p1,&p2,&p3);
scanf("%s",str+1);
int len = strlen(str+1);
int i,j,k;
for (i=1;i<=len;i++){
char c = str[i];
if(c == '-'){
if(!((str[i-1] >='a' && str[i+1]<='z') || (str[i-1] >='0' && str[i+1]<='9')) ){
printf("-");
continue;
}
if( str[i-1] >= str[i+1]){
printf("%c",c);
}
else if( str[i-1] +1 == str[i+1])
continue;
else {
idx = 0;
memset(tmp,0,sizeof(tmp));
for(j=str[i-1]+1 ;j<str[i+1];j++){
for (k=1;k<=p2;k++){
if( p1 == 1)
tmp[idx++] = tolower(j);
else if( p1 == 2)
tmp[idx++] = toupper(j);
else
tmp[idx++] = '*';
}
}
if( p3 == 1) {
printf("%s",tmp);
} else {
int l = strlen(tmp);
for(k=l-1;k>=0;k--){
printf("%c",tmp[k]);
}
}
}
}
else
printf("%c",c);
}
return 0;
}复杂度
设输出长度为
总结
字符串展开题的难点在合法区间判定;把无效连字符先原样保留,可明显简化后续逻辑。