观察第二个样例,发现每对斜角相同的字母能贡献出一种不同的走法
有一左上一右下这样的相同字母对就一定合法
二维前缀和来做可以 \(O(nm)\)
Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 1010
#define ll long long
#define pb push_back
//#define int long long
int n, m;
char a[N][N];
namespace force{
vector<vector<char>> ans;
vector<char> v;
void dfs(int x, int y) {
v.pb(a[x][y]);
if (x==n && y==m) ans.pb(v);
if (x<n) dfs(x+1, y);
if (y<m) dfs(x, y+1);
v.pop_back();
}
void solve() {
ans.clear(); v.clear();
dfs(1, 1);
sort(ans.begin(), ans.end());
for (int i=2; i<ans.size(); ++i) {
if (ans[i-2]==ans[i-1] && ans[i-1]==ans[i]) {puts("1"); return ;}
}
puts("0");
}
}
namespace task{
int sum[N][N], tem[N][N];
void solve() {
memset(sum, 0, sizeof(sum));
memset(tem, 0, sizeof(tem));
for (int i=1; i<=n; ++i) {
for (int j=1; j<=m; ++j) {
sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
if (i<n && j<m) {
if (a[i+1][j]==a[i][j+1]) {
if (sum[i-1][j-1] || tem[i][j-1] || tem[i-1][j]) {puts("1"); return ;}
else ++sum[i][j], ++tem[i][j];
}
}
}
}
puts("0");
}
}
signed main()
{
freopen("water.in", "r", stdin);
freopen("water.out", "w", stdout);
int T;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &m);
for (int i=1; i<=n; ++i) scanf("%s", a[i]+1);
// force::solve();
task::solve();
}
return 0;
}