#include <cstdio> #include <cstring> using namespace std; const int N = 100; short g[N][N]; bool check(int x1, int y1, int x2, int y2); int main() { int n, m; char ch; int x1, y1, x2, y2; int cnt; #ifndef ONLINE_JUDGE freopen("uva_in.txt", "r", stdin); #endif while (scanf("%d", &n) && n) { scanf("%d", &m); for (int i = 0; i < n; i++) { for (int j = 0; j < m; ) { ch = getchar(); if (ch == '0' || ch == '1') { g[i][j++] = ch - '0'; } } } cnt = 0; for (x1 = 0; x1 < n; x1++) { for ( y1 = 0; y1 < m; y1++) { for (x2 = x1; x2 < n; x2++) { for (y2 = y1; y2 < m; y2++) { if (check(x1, y1, x2, y2)) cnt++; } } } } printf("%d\n", cnt); } return 0; } bool check(int x1, int y1, int x2, int y2) { for (int i = x1; i <= x2; i++) { for (int j = y1; j <= y2; j++) { if (g[i][j] != 1) return false; } } return true; }
上面用的是枚举法,效率不高,改成组合的计数方法,代码如下
#include <cstdio> #include <algorithm> #include <climits> using namespace std; #pragma warning(disable:4996) const int N = 110; int dp[N][N]; int row, col; char buf[N]; bool input() { scanf("%d", &row); if (row == 0) return false; scanf("%d", &col); for (int i = 1; i <= row; i++) { scanf("%s", buf); for (int j = 1; j <= col; j++) { if (buf[j - 1] == '1') dp[i][j] = 1; else dp[i][j] = 0; } } return true; } void solve() { for (int i = 2; i <= row; i++) { for (int j = 1; j <= col; j++) { if (dp[i][j]) dp[i][j] += dp[i - 1][j]; } } int ans = 0; for (int i = 1; i <= row; i++) { for(int j = 1; j <= col; j++) { int tmp = INT_MAX; for (int k = j; k <= col && dp[i][k]; k++) { tmp = min(tmp, dp[i][k]); ans += tmp; } } } printf("%d\n", ans); } int main() { #ifndef ONLINE_JUDGE freopen("f:\\OJ\\uva_in.txt", "r", stdin); #endif while (input()) { solve(); } return 0; }