HDOJ-1513-Palindrome

Palindrome

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4139    Accepted Submission(s): 1414


Problem Description
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.
 

Input
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.
 

Output
Your program is to write to standard output. The first line contains one integer, which is the desired minimal number.
 

Sample Input
5 Ab3bd
 

Sample Output
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][N];
}

int main()
{
	while(scanf("%d",&N)!=EOF)
	{
		getchar();//吸收換行符
		for(int n=0;n<N;n++)
		scanf("%c",&a[n]);
		for(int i=0,j=N-1;j>=0;i++,j--)
		b[i]=a[j];//逆轉數組
		a[N]='\0';b[N]='\0';
		printf("%d\n",N-lcs(a,b));
	}
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章