abc260_g Scalene Triangle Area 题解
Scalene Triangle Area
题意
给定一个大小为 X
或者 O
。
对于一个位于 o
和一个格子
, 。 。
给定
思路
分为两种做法。
0x00
推一推式子,可以发现:
- 第
行第 列的O
都可以控制 。 - 第
行第 列的O
都可以控制 。 - 以此类推。
- 第
行第 列与第 列的O
可以控制 。 - 第
行没有可以控制 的格子。
做法就出来了,对于每次询问在线求答案即可。
还有一个小问题,枚举每一行和每一列求答案是
#include <iostream> using namespace std; int n, m, q, x, y, sum[2010][2010]; char c; int main () { ios::sync_with_stdio(0), cin.tie(0); cin >> n >> m; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { cin >> c; sum[i][j] = sum[i][j - 1] + (c == 'O'); // n 行的前缀和 } } for (cin >> q; q; q--) { cin >> x >> y; int cnt = 0; for (int i = 0; i < m && x - i; i++) { // 枚举每一行,如果超出矩阵范围就退出循环 cnt += sum[x - i][y] - sum[x - i][max(0, y - 2 * (m - i))]; // 前缀和 } cout << cnt << '\n'; } return 0; }
0x01
二维差分。
对于一个位于 O
,可以控制的范围如上,其他的自己推一下(
先对于每一行列差分一下,变成下图:
观察上图,可以发现:第一列可以轻松的用行差分优化,但后面的
我们要引入一个差分思想:一个不行就两个!
把这个差分矩阵拆成两个,在最后还原时将两个矩阵加起来。
左边矩阵差分点只有两个,可以
仔细观察一下,欸,
将右边矩阵优化成下图:
差分矩阵通过前缀和思想还原原矩阵,上图每次只要加上
具体实现看代码。
#include <iostream> using namespace std; int n, m, q, x, y, sum[2010][2010], num[2010][12010][2]; // 注意数组的大小 char c; int main () { ios::sync_with_stdio(0), cin.tie(0); cin >> n >> m; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { cin >> c; if (c == 'O') { num[i][j][0]++, num[min(n + 1, i + m)][j][0]--; // 左边矩阵 num[i][j + 2 * m][1]--, num[min(n + 1, i + m)][j][1]++; // 右边矩阵 } } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n + 2 * m; j++) { num[i][j][1] += num[i - 1][j + 2][1]; // 左右矩阵各自进行还原 num[i][j][0] += num[i - 1][j][0]; if (j <= n) { sum[i][j] = sum[i][j - 1] + num[i][j][1] + num[i][j][0]; // 最终的矩阵还原 } } } for (cin >> q; q; q--) { cin >> x >> y; cout << sum[x][y] << '\n'; } return 0; }
本文作者:wnsyou の blog
本文链接:https://www.cnblogs.com/wnsyou-blog/p/17405355.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步