ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

LuoguP1098 字符串的展开 题解

2021-12-23 21:36:44  阅读:127  来源: 互联网

标签:字符 LuoguP1098 int 题解 特判 char && 字符串 include


Update

  • \(\texttt{2020.9.13}\) 重新排版了一下此题解,并修改了一些措辞,删除了一些已经废掉了的东西和废话。

Content

给定一个字符串 \(s\),和三个参数 \(p_1,p_2,p_3\),求按照题目中的规则扩展之后的字符串。

规则实在无法简要概括,请前往原题题面查看。

数据范围:\(1\leqslant p_1\leqslant 3,1\leqslant p_2\leqslant 8,1\leqslant p_3\leqslant 2\),字符串长度不超过 \(100\)。

Solution

这题其实就是一道纯粹的模拟,而且什么优化都不要就可以 AC。

Part 1 特判

首先,输入完之后,将字符串的长度用一变量储存。接着,先用一个 for 循环来遍历字符串内每一个字符。这就要提到我们程序里第一个,也是最长的一个特判。其中:

  • \(i\) 表示字符在字符串中的位置。
  • \(a\) 是输入的字符数组。
if(a[i] == '-' && a[i - 1] < a[i + 1] && ((a[i - 1] >= 'a' && a[i + 1] <= 'z') || (a[i - 1] >= '0' && a[i + 1] <= '9')))

是不是看着有点头晕?别着急,咱们一步一个踏实的脚印,仔细分析一下这一段代码。

这段代码其实就是在判断这个字符是否满足展开的条件。你可能有问题了,不需要特判 \(i\) 是不是第一个或最后一个么?其实,字符数组有一个特性,就是在超过字符数组开的范围的时候默认为空(亲测证实当字符数组的位置为负数时也是默认为空)。那么首先要特判的,是这个字符得要是-才有可能展开,接下来是判断-前面的字符是不是严格小于后面的字符。后面的四个条件,就是说两个字符是否都是小写字母或数字(注意!因为两个字符都是同一类型且前面的字符严格小于后面的字符,所以,判断完后面的字符小于z9,前面的字符就一定小于z9。同理,判断完前面的字符大于a0,后面的字符就一定大于a0)。

总结一下,上面的特判就是在做以下的内容:

  1. 是否是-这个字符
  2. 是否满足前面的字符严格小于后面的字符
  3. 两个字符是否是同一个类型

第二个特判是在输出的时候(以 \(p_1=2,p_3=1\) 时为例):

for(char j = a[i - 1] + 1; j <= a[i + 1] - 1; ++j)
							for(int k = 1; k <= p2; ++k) {
//								puts((j >= 'a') && (j <= 'z') && (j > '9') ? "YES" : "NO");
								printf("%c", (j >= 'a' && j <= 'z' && j > '9') ? j - 32 : j);
							}

以下是对这段代码的解释:

  1. 因为当 \(p_1=1\) 时,输出小写字母,所以不需要特判左右是不是大写字母。
  2. 注释的内容是我在中间调试时加上去的。可以把它忽略。

当 \(p_2=2\) 时,如果前后是小写字母,就要将输出的字符改为大写字符,才能输出正确。

Part 2 过程

首先,如果 \(p_1=1\),那么得先判断是倒序输出还是顺序输出。判断完以后,注意!输出展开的部分里没有两端字母,所以,执行语句时,开始结束的两端应该是-前的字母在字母表中后一个字母(例如,a的后一个字母应该是b)和-后的字母在字母表中前一个字母(例如,z的前一个字母应该是y)。这可以用一个 for 循环实现:

for(char j = a[i + 1] - 1; j >= a[i - 1] + 1; --j)

然后,再将其输出 \(p_2\) 次,这也可以用一个 for 循环来实现:

for(int k = 1; k <= p2; ++k)

\(p_1=2\) 的时候也是同样的道理,只需注意一下特判就行了。

\(p_1=3\) 的时候,将上面的j循环和k循环复制下来,然后输出的内容改为*就行了。

以上是所有分析的内容,若仍有不懂的地方,可以看以下的代码来加深理解。

Code

1 Final Version\(\small\texttt{ 27ms~/~696.00KB}\)

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <iostream>
using namespace std;

int p1, p2, p3;
string a;
int main() {
//	freopen("expand.in", "r", stdin);
//	freopen("expand.out", "w", stdout);
		scanf("%d%d%d", &p1, &p2, &p3);
		cin >> a;
		int len = a.size();
		for(int i = 0; i < len; ++i) {
			if(a[i] == '-' && a[i - 1] < a[i + 1] && ((a[i - 1] >= 'a' && a[i - 1] <= 'z' && a[i + 1] >= 'a' && a[i + 1] <= 'z') || (a[i - 1] >= '0' && a[i - 1] <= '9' && a[i + 1] >= '0' && a[i + 1] <= '9'))) {
				if(p1 == 1) {
					if(p3 == 2)
						for(char j = a[i + 1] - 1; j >= a[i - 1] + 1; --j)
							for(int k = 1; k <= p2; ++k)
								printf("%c", j);
					else
						for(char j = a[i - 1] + 1; j <= a[i + 1] - 1; ++j)
							for(int k = 1; k <= p2; ++k) {
								printf("%c", j);
							}
				} else if(p1 == 2) {
					if(p3 == 2)
						for(char j = a[i + 1] - 1; j >= a[i - 1] + 1; --j)
							for(int k = 1; k <= p2; ++k)
								printf("%c", (j >= 'a' && j <= 'z' && j > '9') ? j - 32 : j);
					else
						for(char j = a[i - 1] + 1; j <= a[i + 1] - 1; ++j)
							for(int k = 1; k <= p2; ++k) {
//								puts((j >= 'A') && (j <= 'Z') && (j > '9') ? "YES" : "NO");
								printf("%c", (j >= 'a' && j <= 'z' && j > '9') ? j - 32 : j);
							}
				} else if(p1 == 3) {
					for(char j = a[i + 1] - 1; j >= a[i - 1] + 1; --j)
							for(int k = 1; k <= p2; ++k)
								printf("*");
				}
			}else if(a[i] == '-' && a[i + 1] == a[i - 1] + 1)
				printf("%c%c", a[i - 1], a[i + 1]); 
			 else
				printf("%c", a[i]);
		}
//	fclose(stdin);
//	fclose(stdout);
	return 0;
} 

2 First Version

此为笔者在 2019 年参加的包含此题的模拟赛时的代码,请忽略 \(\mathcal{O}(3)\) 优化(亲测发现不加也能过)。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <iostream>
#pragma GCC optimize(3)
using namespace std;

int p1, p2, p3;
string a;
int main() {
//	freopen("expand.in", "r", stdin);
//	freopen("expand.out", "w", stdout);
		scanf("%d%d%d", &p1, &p2, &p3);
		cin >> a;
		int len = a.size();
		printf("%c", a[0]);
		for(int i = 1; i < len - 1; ++i) {
			if(a[i] == '-' && a[i - 1] < a[i + 1] && ((a[i - 1] >= 'A' && a[i - 1] <= 'Z' && a[i + 1] >= 'A' && a[i + 1] <= 'Z') || (a[i - 1] >= 'a' && a[i - 1] <= 'z' && a[i + 1] >= 'a' && a[i + 1] <= 'z') || (a[i - 1] >= '0' && a[i - 1] <= '9' && a[i + 1] >= '0' && a[i + 1] <= '9'))) {
				if(p1 == 1) {
					if(p3 == 2)
						for(char j = a[i + 1] - 1; j >= a[i - 1] + 1; --j)
							for(int k = 1; k <= p2; ++k)
								printf("%c", (j >= 'A' && j <= 'Z' && j > '9') ? j + 32 : j);
					else
						for(char j = a[i - 1] + 1; j <= a[i + 1] - 1; ++j)
							for(int k = 1; k <= p2; ++k) {
//								puts((j >= 'A') && (j <= 'Z') && (j > '9') ? "YES" : "NO");
								printf("%c", (j >= 'A' && j <= 'Z' && j > '9') ? j + 32 : j);
							}
				} else if(p1 == 2) {
					if(p3 == 2)
						for(char j = a[i + 1] - 1; j >= a[i - 1] + 1; --j)
							for(int k = 1; k <= p2; ++k)
								printf("%c", (j >= 'a' && j <= 'z' && j > '9') ? j - 32 : j);
					else
						for(char j = a[i - 1] + 1; j <= a[i + 1] - 1; ++j)
							for(int k = 1; k <= p2; ++k) {
//								puts((j >= 'A') && (j <= 'Z') && (j > '9') ? "YES" : "NO");
								printf("%c", (j >= 'a' && j <= 'z' && j > '9') ? j - 32 : j);
							}
				} else if(p1 == 3) {
					for(char j = a[i + 1] - 1; j >= a[i - 1] + 1; --j)
							for(int k = 1; k <= p2; ++k)
								printf("*");
				}
			}else if(a[i] == '-' && a[i + 1] == a[i - 1] + 1)
				printf("%c%c", a[i - 1], a[i + 1]); 
			 else
				printf("%c", a[i]);
		}
		printf("%c", a[len - 1]);
//	fclose(stdin);
//	fclose(stdout);
	return 0;
} 

Conclusion

总的来说,这个题目其实就是一个暴力模拟,不过呢需要注意一些特判和输出的技巧。只要把题目理解了,同类型的题目自然就会做了。

标签:字符,LuoguP1098,int,题解,特判,char,&&,字符串,include
来源: https://www.cnblogs.com/Eason-AC/p/15725311.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有