您的位置:首页 > 其它

HDOJ-1513-Palindrome

2015-08-12 08:53 218 查看

Palindrome

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 4139    Accepted Submission(s): 1414


[align=left]Problem Description[/align]
A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a program which, given a string, determines the minimal number of characters to be inserted
into the string in order to obtain a palindrome.

As an example, by inserting 2 characters, the string "Ab3bd" can be transformed into a palindrome ("dAb3bAd" or "Adb3bdA"). However, inserting fewer than 2 characters does not produce a palindrome.

 

[align=left]Input[/align]
Your program is to read from standard input. The first line contains one integer: the length of the input string N, 3 <= N <= 5000. The second line contains one string with length N. The string is formed from uppercase letters from
'A' to 'Z', lowercase letters from 'a' to 'z' and digits from '0' to '9'. Uppercase and lowercase letters are to be considered distinct.

 

[align=left]Output[/align]
Your program is to write to standard output. The first line contains one integer, which is the desired minimal number.

 

[align=left]Sample Input[/align]

5
Ab3bd

 

[align=left]Sample Output[/align]

2

 
 

题目翻译:

输入一个数n,下一行输入n长的字符串,输出最少需要添加多少个字符才能将其变成回文串(大小写字母不同,包含数字)

思路:

回文,即正着读和倒着读一样,那就以正读顺序为横标,逆读顺序为纵标,求其最长公共子序列(LCS),拿(n-最长公共序列),既是最少要添的字符数;

另外,直接建立5000*5000矩阵会爆内存,所以采用滚动数组,根据LCS原理,每次比较,行=列时,左上角+1,否则取左边和上边的较大者,因此每次运算只涉及两行,其余的都是无效行,因此数组开2*5000足以,行号在0-1间交替滚动。

 

一道又气又恼的题,代码里记录长度的滚动数组应为int,结果顺手写进了char,导致存进整数输出整数在本地可以运行,在oj上一直WA,出错在定义行,找了好久才发现,引以为戒

#include<cstdio>
#include<cstring>
#define MAX 5050
#define gun (m?0:1)//由此式实现m在0-1间切换,亦可写成(m+1)%2
int N;
char a[MAX],b[MAX];
int s[2][MAX];//滚动数组,两行足以;定义出错在此
int max(int a,int b)//这个可写成#define max(a,b) a>b?a:b代替
{
return a>b?a:b;
}

int lcs(char a[],char b[])
{
int m=1;
memset(s,0,sizeof(s));//清空滚动数组
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
if(a[i]==b[j])
s[m][j+1]=s[gun][j]+1;//另一行对线位+1
else
s[m][j+1]=max(s[m][j],s[gun][j+1]);//左一位和上一位较大者
}
m=gun;//换行
}
return s[gun]
;
}

int main()
{
while(scanf("%d",&N)!=EOF)
{
getchar();//吸收换行符
for(int n=0;n<N;n++)
scanf("%c",&a
);
for(int i=0,j=N-1;j>=0;i++,j--)
b[i]=a[j];//逆转数组
a
='\0';b
='\0';
printf("%d\n",N-lcs(a,b));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: