题目描述 Description
输入描述 Input
Description
输入数据第一行只有一个n,表示有个字符串。
接下来有n行,每行一个字符串。
输出描述 Output
Description
输出有n行,每行一个字符串,表示按对称系数从大到小排序后的字符串,对称系数相同时按字典序排序。
样例输入 Sample
Input
5
pineapple
banana
peach
coconut
character
样例输出 Sample
Output
banana
character
pineapple
coconut
peach
数据范围及提示 Data Size &
Hint
数据范围:
1<=n<=100
1<=len<=500
1<=k<=len
提示:
对称系数k是指最长对称子序列的长度,非最长对称子串的长度。
分类标签 Tags 点此展开
所谓的字典序:就是ASCII码顺序,可以直接由strcmp比较出来
注意:c++除了0以外,正数负数都是真,!X只有x是0的时候才是真,其余时候都是假
思路一:将这个字符串反转,然后求两个字符串的最长公共子序列。
代码一:
#include<
cstdio >
#include<
iostream >
#include<
cstring >
#include<
algorithm >
using namespace
std;
int
dp[2333][2333];
struct str{
}l[2333];
bool cmp(str
a,str b)
{
}
int main()
{
}
思路二:序列型DP,由小区间的对称长度扩展到大区间的最长对称
代码二:
#include<
cstdio >
#include<
cstring >
#include<
iostream >
#include<
algorithm >
using namespace
std;
const int
N=101;
const int
LEN=501;
struct Dc{
char a[LEN];//dan
ci
int k;//xi
shu
};
Dc dc[N];
int
n,f[LEN][LEN];
void
input()
{
scanf("%d",&n);
for(int
i=1;i<=n;++i)
scanf("%s",dc[i].a+1);
}
void DP()
{
for(int
l=1;l<=n;++l)
{
memset(f,0,sizeof(f));
int
len=strlen(dc[l].a+1);
for(int
i=1;i<=len;++i)
f[i][i]=1;
for(int
i=len-1;i>=1;--i)
{
f[i][j]=2;
continue;//防止语句再走else语句
}
f[i][j]=max(max(f[i+1][j],f[i+1][j-1]+2),f[i][j-1]);
dc[l].k=f[1][len];
//cout<<f[1][len]<<endl;
}
}
int cmp(const
struct Dc &b,const struct Dc &c)
{
if((b.k>c.k)||(b.k==c.k&&strcmp(b.a+1,c.a+1)<0))
return 1;//注意只有<0也是真
return 0;
}
int main()
{
input();
DP();
sort(dc+1,dc+n+1,cmp);
for(int
i=1;i<=n-1;++i)
printf("%s
",dc[i].a+1);
printf("%s",dc[n].a+1);
return 0;
}