#include <iostream> #include<vector> using namespace std; //动态规划,dp[i][j]代表以s[i-1]和t[j-1]结尾的最长公共子串 //状态转移:如果s[i-1]==t[j-1],则dp[i][j]=dp[i-1][j-1]+1;如果不相等则dp[i][j]=0; //边界条件:dp[0][j]=0;dp[i][0]=0; //只用到左上的数据,用一个额外空间记录即可 int main() { string s,t; cin>>s>>t; int m=s.size(); int n=t.size(); int maxlen=0;//记录最长的公共子串长度 int pos=300;//记录了最长子串的结尾位置 vector<int>dp(n+1,0); for(int i=1; i<=m; i++) { int prev=dp[0];//从头开始记录左上位置 for(int j=1; j<=n; j++) { int old=dp[j];//记录修改前的值 if(s[i-1]==t[j-1]) { dp[j]=prev+1; if(maxlen<=dp[j]) { int tmp= m>=n? j-1 : i-1 ;//记录最长公共子串结尾在较短串中的位置 if(maxlen<dp[j] || tmp<pos)//两种情况需要更新结尾位置 pos=tmp; maxlen=dp[j];//更新最大值 } } else dp[j]=0; //左上记录右移一位 prev=old; } } //输出最长公共子串 if(m>=n) { for(int i=pos-maxlen+1; i<=pos; i++) cout<<t[i]; } else { for(int i=pos-maxlen+1; i<=pos; i++) cout<<s[i]; } return 0; } // 64 位输出请用 printf("%lld")