码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2020-08-02 19:57:08      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:简单   字符串排序   不能   include   break   for   scan   处理   class   

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

  • 对给定的字符串\(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\n",ans+1); 
	return 0;
}

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

标签:简单   字符串排序   不能   include   break   for   scan   处理   class   

原文地址:https://www.cnblogs.com/Lour688/p/13420057.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!