题目描述 Description
小A想买一顶新帽子,商店里有n个帽子 (1<=n<=100),每顶帽子上有一个字符串,字符串的长度为len (1<=len<=500)。她认为每顶帽子上的字符串看起来越对称则代表这顶帽子更漂亮。根据每个字符串,我们可以算出其对称系数k (即最长对称子序列的长度) 来比较各顶帽子在小A心中的漂亮程度。
例如,字符串 character (k=5) 比 pollution (k=4) 更对称,apple (k=2) 比 pear (k=1) 更对称。
现在给定n个字符串,请将它们按对称系数排序后从大小输出 (k相同时按字典序排序)。
输入描述 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是指最长对称子序列的长度,非最长对称子串的长度。
对于一个字符串的最长对称子序列,就是它和它反串的最长公共子序列,对于每个串暴力计算即可。
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[2333][2333];
struct str{
string s;
int len;
}l[2333];
bool cmp(str a,str b)
{
if(a.len!=b.len) return a.len>b.len;
return a.s<b.s;
}
int main()
{
int n;
scanf("%d",&n);
for(int k=1;k<=n;k++)
{
cin>>l[k].s;
string ss;
memset(dp,0,sizeof(dp));
int len=l[k].s.length();
for(int i=len-1;i>=0;i--) ss+=l[k].s[i];
for(int i=0;i<len;i++)
{
for(int j=0;j<len;j++)
{
if(l[k].s[i]==ss[j])
dp[i+1][j+1]=max(dp[i][j]+1,max(dp[i+1][j],dp[i][j+1]));
else
dp[i+1][j+1]=max(dp[i+1][j],dp[i][j+1]);
}
}
l[k].len=dp[len][len];
// cout<<l[k].len<<endl;
}
sort(l+1,l+1+n,cmp);
for(int i=1;i<=n;i++)
{
cout<<l[i].s<<endl;
}
return 0;
}