蓝桥杯2016初赛]密码脱落
题目描述
X星球的考古学家发现了一批古代留下来的密码。这些密码是由A、B、C、D 四种植物的种子串成的序列。
仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串)。
由于年代久远,其中许多种子脱落了,因而可能会失去镜像的特征。
你的任务是:给定一个现在看到的密码串,计算一下从当初的状态,它要至少脱落多少个种子,才可能会变成现在的样子。
仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串)。
由于年代久远,其中许多种子脱落了,因而可能会失去镜像的特征。
你的任务是:给定一个现在看到的密码串,计算一下从当初的状态,它要至少脱落多少个种子,才可能会变成现在的样子。
输入
输入存在多组测试数据,对于每组测试数据输入一行,表示现在看到的密码串(长度不大于1000)
输出
对于每组测试数据要求输出一个正整数,表示至少脱落了多少个种子。
样例输入 Copy
ABCBA
ABDCDCBABC
样例输出 Copy
0
3
题解:
求出原字符串和反转字符串的最长公共子序列长度,和字符串长度相减即可,LCS的应用
#include<iostream> #include<math.h> #include<string.h> #include<string> #include<algorithm> using namespace std; int dp[2000][2000]; int len1,len2; void lcs(string s1,string s2) { for(int i=0;i<=len1;i++)//初始化 dp[i][0]=0; for(int i=0;i<=len2;i++) dp[0][i]=0; for(int i=1;i<=len1;i++) { for(int j=1;j<=len2;j++) { if(s1[i-1]==s2[j-1]) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); } } } void Print(string s1,string s2)//输出公共子序列 { string str=""; while(len1>=1&&len2>=1)//从字符串s1,s2的末尾位置往前推 { if(s1[len1-1]==s2[len2-1]) { str=str+s1[len1-1]; len1--; len2--; } else { if(dp[len1][len2-1]>dp[len1-1][len2])//说明公共的字符在字符串s1的i位置之前,与字符s2[j]无关 len2--; else len1--; } } for(int i=str.length();i>=0;i--) cout<<str[i]<<' '; cout<<endl; } int main() { string s1,s2; while(cin>>s1) { s2=s1; reverse(s2.begin(),s2.end()); len1=s1.length(); len2=s2.length(); lcs(s1,s2); cout<<len1-dp[len1][len2]<<endl; } return 0; }
等风起的那一天,我已准备好一切