1. 程式人生 > >noip模擬賽 蒜頭君打地鼠

noip模擬賽 蒜頭君打地鼠

分數 getchar() 技術 sum 打地鼠 mage names 維護 max

技術分享

技術分享技術分享

技術分享

分析:直接一個一個地去暴力枚舉分數比較少,我們需要一種比較快的統計一定空間內1的數量,標準做法是前綴和,但是二維前綴和維護的是一個矩形內的值,這個是旋轉過的該怎麽辦?可以把圖旋轉45°,不過這樣比較考驗碼力,我們可以考慮維護每一行的前綴和,寫得好常數小一點加上讀入優化就能A了.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

long long ans = 0,n, m, sum[2010][2010
]; long long read() { long long res = 0, f = 1; char ch = getchar(); while (ch < 0 || ch > 9) if (ch == -) { f = -1; ch = getchar(); } while (ch >= 0 && ch <= 9) { res = res * 10 + ch - 0; ch
= getchar(); } return res * f; } int main() { n = read(); m = read(); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { sum[i][j] = read(); sum[i][j] += sum[i][j - 1]; } for (int i = 1; i <= n; i++) for
(int j = 1; j <= n; j++) { long long maxx = sum[i][min(n, j + m - 1)] - sum[i][max((long long)0, j - m)]; for (int k = 1; k < m; k++) { int l = max(j - m + k,(long long)0), r = min(j + m - 1 - k,n); if (i + k <= n) maxx += sum[i + k][r] - sum[i + k][l]; if (i - k >= 1) maxx += sum[i - k][r] - sum[i - k][l]; } ans = max(maxx, ans); } printf("%lld\n", ans); return 0; }

noip模擬賽 蒜頭君打地鼠