LG10270
思路十分简单,但需要一定的转化,好题。
记 \(s_{i,j}\) 表示第 \(i\) 行的第 \(j\) 个字符。考虑任意一点 \((i,j)\),假设在此之前没有经过字母不同的路径,若 \(s_{i,j+1}\) 和 \(s_{i+1,j}\) 不同,则可以分别往这两个方向走,最长公共前缀也就固定下来了,长度为 \(i+j-1\)。
于是我们就可以暴力枚举每个点并判断是否可以在此分支,若可以则更新答案。这样做对于在 \((i,j)\) 之前不同的路径也可以更新,保证了正确性。时间复杂度 \(O(nm)\)。
代码如下:
#include <iostream>
#include <cstdio>
using namespace std;
int n,m,a[4001][4001],ans;
string s;
int main()
{
cin >> n >> m;
for( int i = 1 ; i <= n ; i ++ )
{
cin >> s;
for( int j = 0 ; j < m ; j ++ )
a[i][j + 1] = s[j] - 'a';
}
ans = n + m - 1;
for( int i = 1 ; i < n ; i ++ )
for( int j = 1 ; j < m ; j ++ )
if( a[i][j + 1] != a[i + 1][j] )
ans = min( ans , i + j - 1 );
cout << ans;
return 0;
}
还是菜。