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; }
相关文章推荐
- HDU 3853 LOOPS(期望DP)(第一篇期望dp)
- C++ <VS2008> 使用Excel类创建,读取,查询,写入,修改,删除
- 手动实现数组slice方法跟splice方法
- WINCE注册表中IClass值的确定
- hdu 1075 What Are You Talking About (字典树·文字翻译)
- STL之一:map用法详解
- 360在线笔试编程题
- c++ 11 游记 之 decltype constexpr
- javafx drag
- FZU Problem 1853 Number Deletion
- 【Maven】第一次使用maven的配置(win8,eclipse,Intellij IDEA)
- Codeforces Round #315 (Div. 2)569D Symmetric and Transitive(dp)
- iOS测试
- Gym - 100625B Bribe
- Linux中搭建SVN服务器
- libCURL开源库在VS2010环境下编译安装,配置详解
- spring注入失败 Injection of resource dependencies failed
- HDOJ-1503-Advanced Fruits
- Java并发编程:阻塞队列
- owncloud源码分析5--CAS单点登录