题解 P1124 文件压缩 (字符串+思维/模拟)

Posted lour688

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 P1124 文件压缩 (字符串+思维/模拟)相关的知识,希望对你有一定的参考价值。

这道题的基本思路简单来说就是:

  • 对给定的字符串(S1)排序,得到字符串(S2)(S1)是各种情况中字符串末位的集合,(S2)也就是首位的集合,下标相同的属于同一种情况

  • 每种情况中首位与末位字符在原字符串中都是相邻的(当然如果首位是原字符串的首位的话末位就是原字符串的末位了,但这种情况不会干扰我们解题)由此不断递推得出原字符串。

并且我在此解释一下为什么不能正着推,题解中和讨论中我没有找到解释,并且又有很多人有疑问。

  • 不能正着推,因为正着推肯定得从给你的序列中按顺序找,但是给你的序列是各个字符串的尾字符,无序啊

  • 当然如果大家能处理一下,解决这个问题就可以正着推啦

其实这道题自己写的话就是可能会麻烦一点导致不想去想,但确实是比较简单的

代码如下,有一些注释,可能比较好懂:

#include <bits/stdc++.h>
using namespace std;
const int maxn=10000+5;
int n,p;
char s[maxn],ss[maxn]; // s[]是题目给的,ss[]是你排出的对应的各个字符串首位
char ans[maxn];
int main(){
	//freopen("1.in","r",stdin);
	scanf("%d%s%d",&n,s+1,&p);
	memcpy(ss+1,s+1,sizeof s);
	sort(ss+1,ss+1+n); // 对原字符串排序得到首位
	int cnt=n+1; //cnt 用于记录答案
	for(int i=1;i<=n;++i) if(ss[i]==s[p]) { p=i;break; } //找到 s[p] 即答案中最后一个字符
	while(cnt>1){ // 不能正着推,因为正着推肯定得从给你的序列中按顺序找,但是给你的序列是各个字符串的尾字符,无序啊
		ans[--cnt]=s[p]; //将s[p]作为当前未确定的答案的最后一位
		ss[p]=‘#‘;//ss[p] 是 s[p]的前一位,确定s[p]前一步是确定ss[p],他们下标相同(都是p)。 现在s[p]已有贡献,ss[p] 没用了,为了排除干扰置为‘#‘
		for(int i=n;i>=1;--i) if(ss[i]==s[p]) {p=i;break;} //找到一个与本次while的s[p]相同的一个ss[p],进而推出s[p]的前一位
	}						           //因为找ss[p]是在ss[]中,ss有序,所以一定会找到一个合法的,不会算重
	printf("%s
",ans+1); 
	return 0;
}

以上是关于题解 P1124 文件压缩 (字符串+思维/模拟)的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 P1124 文件压缩

洛谷P1124 文件压缩

牛客白月赛33题解 待补

易位构词EOJ3451字符串思维题模拟

模拟赛 提米树 题解 (DP+思维)

第九届“图灵杯”NEUQ-ACM程序设计竞赛个人题解