看到题,想到leetcode的最大正方形,但是好像没什么关系,不会做!后来听同学讲解,说是二分答案,但是想不清楚怎么校验这个答案的正确性,就是给定正方形边长k,如何验证k是否满足!
后来又问他,才知道就是简单的暴力枚举!感觉自己真是菜,这也没想到!
1.遇到一个题,看能否二分的条件,一个是答案的单调性,一个是快速检查给定答案的正确性,缺一不可,关键是快速检查答案是否可行这个问题比较难,需要一些枚举手段。
2.还有一个想法是:就满足什么条件的最大值,转化成给定答案所需要的最小条件是否满足,这种方法也很重要,暂时想不起来答案了,遇到的时候再写出来。好像是上次cf的一道什么题目,有时间查找一下!http://codeforces.com/contest/735/problem/C
代码如下:
1 /* 2 ID: y1197771 3 PROG: test 4 LANG: C++ 5 */ 6 #include<bits/stdc++.h> 7 #define pb push_back 8 #define FOR(i, n) for (int i = 0; i < (int)n; ++i) 9 #define dbg(x) cout << #x << " at line " << __LINE__ << " is: " << x << endl 10 typedef long long ll; 11 using namespace std; 12 typedef pair<int, int> pii; 13 const int maxn = 1e3 + 10; 14 int n, m; 15 string s[55]; 16 bool check(int len) { 17 for (int i = 0; i < n - len + 1; i++) { 18 for (int j = 0; j < m - len + 1; j++) { 19 bool f = 1; 20 for (int x = 0; x < len; x++) { 21 f = 1; 22 for (int y = 1; y < len; y++) { 23 if(s[i + x][j + y] != s[i + x][j + y - 1]) { 24 f = 0; break; 25 } 26 } 27 if(f == 0) break; 28 } 29 if(f) return 1; 30 } 31 } 32 return 0; 33 } 34 void solve() { 35 cin >> n >> m; 36 for (int i = 0; i < n; i++) { 37 cin >> s[i]; 38 } 39 int left = 0, right = min(n, m); 40 while(left < right) { 41 int mid = (left + right + 1) / 2; 42 if(check(mid)) { 43 left = mid; 44 } else right = mid - 1; 45 } 46 cout << left * left << endl; 47 } 48 int main() { 49 freopen("test.in", "r", stdin); 50 //freopen("test.out", "w", stdout); 51 ios::sync_with_stdio(0); 52 cin.tie(0); cout.tie(0); 53 int _; cin >> _; 54 while(_--) 55 solve(); 56 return 0; 57 }