您的位置:首页 > 其它

前缀和 Codeforces611C New Year and Domino

2016-01-01 17:34 288 查看
传送门:点击打开链接

题意:告诉你一个地图(5e2*5e2),里面有障碍物,现在告诉你地图里面的一个子矩阵的对角点坐标,求这个子矩阵里能放多少个1*2的多米诺牌

思路:求dp[i][j]表示(1,1)到(i,j)这个子矩阵的的答案,A[i][j]表示第i行的前j列的答案,b[i][j]表示第i列的前j行的答案

那么对于(bx,by),(ex,ey),答案就等于dp[ex][ey]-dp[ex][by]-dp[bx][ey]+dp[bx][by]+A[bx][ey]-A[bx][by-1]+B[by][ex]-B[by][bx-1]

#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<string>
#include<vector>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<algorithm>
#include<functional>
#define fuck(x) cout<<"["<<x<<"]"
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)
using namespace std;
typedef long long LL;
typedef pair<int, int>PII;

const int MX = 500 + 2;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;

int n, m;
char s[MX][MX];
int dp[MX][MX], A[MX][MX], B[MX][MX];

void prosolve() {
memset(dp, 0, sizeof(dp));
memset(A, 0, sizeof(A));
memset(B, 0, sizeof(B));

for(int ex = 1; ex <= n; ex++) {
int cnt = 0;
for(int ey = 1; ey <= m; ey++) {
if(1 < ey && s[ex][ey] == '.' && s[ex][ey - 1] == '.') cnt++;
if(1 < ex && s[ex][ey] == '.' && s[ex - 1][ey] == '.') cnt++;
dp[ex][ey] = dp[ex - 1][ey] + cnt;
}
}

for(int ex = 1; ex <= n; ex++) {
for(int ey = 1; ey <= m; ey++) {
A[ex][ey] = A[ex][ey - 1];
if(1 < ey && s[ex][ey] == '.' && s[ex][ey - 1] == '.') A[ex][ey]++;
}
}

for(int ey = 1; ey <= m; ey++) {
for(int ex = 1; ex <= n; ex++) {
B[ey][ex] = B[ey][ex - 1];
if(1 < ex && s[ex][ey] == '.' && s[ex - 1][ey] == '.') B[ey][ex]++;
}
}
}

int main() {
//FIN;
while(~scanf("%d%d", &n, &m)) {
for(int i = 1; i <= n; i++) {
scanf("%s", s[i] + 1);
}
prosolve();

int Q; scanf("%d", &Q);
while(Q--) {
int bx, by, ex, ey;
scanf("%d%d%d%d", &bx, &by, &ex, &ey);
int ans = dp[ex][ey] - dp[ex][by] - dp[bx][ey] + dp[bx][by];
ans += A[bx][ey] - A[bx][by];
ans += B[by][ex] - B[by][bx];
printf("%d\n", ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: