首页 > 代码库 > Codeforces Round #248 (Div. 1)——Nanami's Digital Board
Codeforces Round #248 (Div. 1)——Nanami's Digital Board
题目连接
- 题意:
给n*m的0/1矩阵,q次操作,每次有两种:1)将x,y位置值翻转 2)计算以(x,y)为边界的矩形的面积最大值
(1?≤?n,?m,?q?≤?1000) - 分析:
考虑以(x,y)为下边界的情况,h=(x,y)上边最多的连续1的个数。那么递减的枚举,对于当前hx,只需要看两侧能到达的最远距离,使得h(x,ty)不大于h即可。之后的枚举得到的两侧距离大于等于之前的,所以继续之前的两侧距离继续枚举即可。
const int maxn = 1100; int n, m, q; int ipt[maxn][maxn]; int up[maxn][maxn], dwn[maxn][maxn], lft[maxn][maxn], rht[maxn][maxn]; int len[maxn]; void updaterow(int r) { FE(j, 1, m) lft[r][j] = (ipt[r][j] == 1 ? lft[r][j - 1] + 1 : 0); FED(j, m, 1) rht[r][j] = (ipt[r][j] == 1 ? rht[r][j + 1] + 1 : 0); } void updatecol(int c) { FE(i, 1, n) up[i][c] = (ipt[i][c] == 1 ? up[i - 1][c] + 1 : 0); FED(i, n, 1) dwn[i][c] = (ipt[i][c] == 1 ? dwn[i + 1][c] + 1 : 0); } int maxarea(int s, int len[], int thes) { int l = s, r = s, ret = 0; FED(i, len[s], 1) { while (l >= 1 && len[l] >= i) l--; while (r <= thes && len[r] >= i) r++; ret = max(ret, i * (r - l - 1)); } return ret; } int main() { while (~RIII(n, m, q)) { FE(i, 1, n) FE(j, 1, m) RI(ipt[i][j]); FE(i, 1, n) updaterow(i); FE(j, 1, m) updatecol(j); REP(kase, q) { int op, x, y; RIII(op, x, y); if (op == 1) { ipt[x][y] ^= 1; updatecol(y); updaterow(x); } else { int ans = max(maxarea(y, up[x], m), maxarea(y, dwn[x], m)); FE(i, 1, n) len[i] = lft[i][y]; ans = max(ans, maxarea(x, len, n)); FE(i, 1, n) len[i] = rht[i][y]; ans = max(ans, maxarea(x, len, n)); WI(ans); } } } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。