P1124 文件压缩 题解
第一眼看到这个题,啊,是道水题!
一个星期后:终于AC了......
大体思路:
文件压缩,妥妥的模拟嘛!
人家题目中正推给的这么详细了,倒推一下还不会吗!
我们可以发现,在字符串排序之前每个字符串的开头和结尾在原字符串中是紧挨着的(显而易见,原字符串的开头和结尾除外)。那么字符串排序后,每个字符串的开头和结尾仍然是紧挨着的。
所以我们只需要排序后每个字符串的开头和结尾,就能求出原字符串了!
字符串 S' 自然就是每个字符串的结尾了,那么开头也很简单,只需要将 $S'$ 进行排序就可以得到。
整理一下思路:
我们先新建一个字符串用来存排序后的 S' (每个字符串的开头元素),然后找到原字符串的开头,从那里开始查找,并一个一个地寻找并压入答案字符串,最终输出答案字符串。
(说道我挂了一周的这件事,主要是因为我把寻找原字符串的开头放到了最后,这就导致了很多麻烦。种种原因,使我只得了......十分。)
这么简单的题,就直接上代码吧。
代码:
#include<iostream> #include<string> #include<algorithm> using namespace std; string s,ss; string ans; int a[10001]={0}; int v[10001]={0}; int main(){ int n,p; cin>>n; cin>>s; ss=s; cin>>p; for(int i=0;i<n;i++){ a[i]=s[i]-'a'; } sort(a,a+n); //用了很笨的方法排序。 for(int i=0;i<n;i++){ s[i]=a[i]+'a'; } int now=0; for(int i=0;i<n;i++){ //寻找原字符串的开头,当时就挂在了这,后来参考大佬的题解才改过来的。 if(s[i]==ss[p-1]){ now=i; v[i]=1; break; } } for(int j=n-1;j>=0;j--){ //计算答案,大体步骤就是找到与上次字符串结尾相同的字符串开头,然后记下它的结尾。 ans[j]=ss[now]; for(int k=n-1;k>=0;k--){ if(ss[now]==s[k]&&v[k]!=1){ now=k; v[k]=1; break; } } } for(int i=0;i<n;i++){ //由于我是边倒向边倒算,所以最终还是要正着输出的。 cout<<ans[i]; } return 0; }
总结:
模拟题目一般比较简单,挂就挂在顺序、边界条件上,这种事情还是要注意的。