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; 
} 
posted @ 2024-05-18 17:25  liyilang2021  阅读(2)  评论(0编辑  收藏  举报