标签:简单 字符串排序 不能 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;
}
标签:简单 字符串排序 不能 include break for scan 处理 class
原文地址:https://www.cnblogs.com/Lour688/p/13420057.html