首页 > 其他分享 >Maximum Number of Points From Grid Queries

Maximum Number of Points From Grid Queries

时间:2023-01-11 17:36:09浏览次数:61  
标签:vector 格子 int Queries Points Grid queries grid size

Maximum Number of Points From Grid Queries

You are given an $m \times n$ integer matrix grid and an array queries of size $k$.

Find an array answer of size $k$ such that for each integer queres[i] you start in the top left cell of the matrix and repeat the following process:

  • If queries[i] is strictly greater than the value of the current cell that you are in, then you get one point if it is your first time visiting this cell, and you can move to any adjacent cell in all $4$ directions: up, down, left, and right.
  • Otherwise, you do not get any points, and you end this process.

After the process, answer[i] is the maximum number of points you can get. Note that for each query you are allowed to visit the same cell multiple times.

Return the resulting array  answer.

Example 1:

Input: grid = [[1,2,3],[2,5,7],[3,5,1]], queries = [5,6,2]
Output: [5,8,1]
Explanation: The diagrams above show which cells we visit to get points for each query.

Example 2:

Input: grid = [[5,2,1],[1,1,2]], queries = [3]
Output: [0]
Explanation: We can not get any points because the value of the top left cell is already greater than or equal to 3.

Constraints:

  • $m ~\mathrm{==}~ \text{grid.length}$
  • $n ~\mathrm{==}~ \text{grid}[i].\text{length}$
  • $2 \leq m, n \leq 1000$
  • $4 \leq m \times n \leq {10}^5$
  • $k ~\mathrm{==}~ \text{queries.length}$
  • $1 \leq k \leq {10}^4$
  • $1 \leq \text{grid}[i][j], \text{queries}[i] \leq {10}^6$

 

解题思路

  暴力做的话可以用并查集,遍历每一个询问,然后再遍历一遍矩阵的每个格子把值小于询问的四个方向格子进行合并,最后输出输出$(0, 0)$所在连通块的格子数目,这种做法的时间复杂度为$O(k \cdot n \cdot m)$,会超时。

  可以发现随着查询的值逐渐增大,那么能合并的格子越多,连通块不断往外扩展而不会减少,$(0, 0)$所在连通块的格子数量也会越大。因此可以进行离线处理,把询问按照值从小到大排序,那么从小到大枚举每个询问时能用到的格子会越来越多。一开始假设矩阵一个格子都没有,从小到大枚举每个询问,把所有值小于当前询问的格子添加到矩阵中,同时往这个格子的四个方向进行合并连通块(合并值小于当前询问的格子),当无法再加入格子时当前询问的答案就是$(0, 0)$所在连通块的格子数量。

  AC代码如下,时间复杂度为$O(nm+k)$:

 1 class Solution {
 2 public:
 3     struct Node {
 4         int val, x, y;
 5         
 6         bool operator<(Node &t) {
 7             return val < t.val;
 8         }
 9     };
10     
11     vector<int> maxPoints(vector<vector<int>>& grid, vector<int>& queries) {
12         int n = grid.size(), m = grid[0].size();
13         vector<Node> g;
14         for (int i = 0; i < n; i++) {
15             for (int j = 0; j < m; j++) {
16                 g.push_back({grid[i][j], i, j});    // 存每个格子的信息
17             }
18         }
19         sort(g.begin(), g.end());   // 按照值把格子从小到大排序
20         vector<int> fa, cnt;
21         for (int i = 0; i < n * m; i++) {
22             fa.push_back(i);
23             cnt.push_back(1);
24         }
25         vector<int> p;
26         for (int i = 0; i < queries.size(); i++) {
27             p.push_back(i);
28         }
29         sort(p.begin(), p.end(), [&](int i, int j) {    // 对询问从小到大排序
30             return queries[i] < queries[j];
31         });
32         vector<int> ans(queries.size());
33         int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
34         function<int(int)> find = [&](int x) {
35             return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);
36         };
37         for (int i = 0, j = 0; i < queries.size(); i++) {
38             while (j < g.size() && g[j].val < queries[p[i]]) {  // 把所有值小于当前询问queries[p[i]]的格子添加到矩阵中
39                 int x = g[j].x, y = g[j].y; // 当前格子的坐标
40                 j++;
41                 for (int k = 0; k < 4; k++) {   // 四个方向合并
42                     int xx = x + dx[k], yy = y + dy[k];
43                     if (xx < 0 || xx >= n || yy < 0 || yy >= m) continue;
44                     if (grid[xx][yy] >= queries[p[i]]) continue;    // 合并值小于当前询问的格子
45                     int a = find(x * m + y), b = find(xx * m + yy);
46                     if (a != b) {
47                         cnt[b] += cnt[a];
48                         fa[a] = b;
49                     }
50                 }
51             }
52             if (queries[p[i]] > grid[0][0]) ans[p[i]] = cnt[find(0)];   // 当前询问就是(0, 0)格子所在连通块的格子数量,同时要保证询问的值大于grid[0][0]
53         }
54         return ans;
55     }
56 };

  当时比赛的时候写的是bfs,不过把队列换成了优先队列。也是离线处理。对于某个询问,我们要求的是从$(0, 0)$开始扩展,每次扩展的格子的值都小于当前查询,最后看看能够扩展多少个格子,因此先把$(0, 0)$压入队列,然后每次从队列弹出元素往四个方向扩展就可以实现。同样发现随着查询的值增加,能够扩展的格子越多,因此在一步步的扩展中,我们应该每次从值最小的格子进行扩展,即每次从队列弹出最小的元素,这样才能够保证对于值较小的询问从$(0, 0)$开始把能够扩展的格子先扩展完,因此要把普通队列换成优先队列。

  每次查看堆顶元素,如果查询的值(从小到大排序)小于等于堆顶元素则表示对于该查询已无法再从该格子进行扩展(且从$(0, 0)$开始能扩展完的格子已扩展完),那么答案就是已扩展的格子数量。

  AC代码如下,时间复杂度为$O(nm\log{nm})$:

 1 class Solution {
 2 public:
 3     struct Node {
 4         int val, x, y;
 5 
 6         bool operator<(const Node &t) const {   // 重载优先队列的<运算符,这里的<比较的是优先级
 7             // 如果a<b为true,意味着a的优先级小于b,那么a在b的下面
 8             // 如果a<b为false,意味着a的优先级大于b,那么a在b的上面
 9             // 由于这里要实现小根堆,因此应该让值小的元素在值大的元素上面
10             return val > t.val; // 如果当前的this->t > t.val,那么返回true,this在t的下面,即更大的值在下面(那么小的就在上面)
11         }
12     };
13     
14     vector<int> maxPoints(vector<vector<int>>& grid, vector<int>& queries) {
15         int n = grid.size(), m = grid[0].size();
16         vector<int> p;
17         for (int i = 0; i < queries.size(); i++) {
18             p.push_back(i);
19         }
20         sort(p.begin(), p.end(), [&](int i, int j) {
21             return queries[i] < queries[j];
22         });
23         priority_queue<Node> q; // 小根堆
24         q.push({grid[0][0], 0, 0});
25         vector<vector<bool>> vis(n, vector<bool>(m));
26         vis[0][0] = true;
27         vector<int> ans(queries.size(), -1);
28         int cnt = 0, idx = 0;   // cnt表示已经扩展的格子数量,idx是查询的下标
29         int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
30         while (!q.empty()) {
31             while (idx < queries.size() && queries[p[idx]] <= q.top().val) {    // 对于当前查询已无法再从堆顶的格子扩展
32                 ans[p[idx++]] = cnt;    // 答案就是已扩展格子的数量
33             }
34             int x = q.top().x, y = q.top().y;   // 弹出值最小的格子
35             q.pop();
36             cnt++;  // 已扩展格子数量加1
37             for (int i = 0; i < 4; i++) {
38                 int xx = x + dx[i], yy = y + dy[i];
39                 if (xx < 0 || xx >= n || yy < 0 || yy >= m) continue;
40                 if (vis[xx][yy]) continue;
41                 vis[xx][yy] = true;
42                 q.push({grid[xx][yy], xx, yy});
43             }
44         }
45         for (auto &it : ans) {  // 最后还没遍历到的查询意味着可以扩展到所有的格子
46             if (it == -1) it = cnt;
47         }
48         return ans;
49     }
50 };

 

参考资料

  力扣第323场周赛:https://www.bilibili.com/video/BV1DD4y1a7JG/

标签:vector,格子,int,Queries,Points,Grid,queries,grid,size
From: https://www.cnblogs.com/onlyblues/p/17044399.html

相关文章

  • Tree and Queries Dsu on tree
    //题意:给出一棵树,树上每个点有一种颜色,给出多个询问,求以a为根的子树上,染色点数超过k的颜色有多少种//思路:很明显可以dsuontree,在写的时候要注意统计答案和清零的复杂度......
  • 自定义JeeSite组件DataGrid中的单选钮radio编辑项
    继续说说JeeSite中提供的DataGrid组件。作为传统的后端生成前端使用JqGrid来显示列表数据是非常方便的,JeeSite框架将JqGrid进行了包装,简化和规范了使用值得称赞,但毕竟JqGri......
  • [LeetCode] 149. Max Points on a Line
    Givenanarrayof points where points[i]=[xi,yi] representsapointonthe X-Y plane,return themaximumnumberofpointsthatlieonthesamestraig......
  • cxgrid汇总数是零显示空白
    TcxDataSummaryItem.OnGetTextprocedureTApportionDeptCost.cxgrdbndtblvwDBBandedTableView1TcxGridDBDataControllerTcxDataSummaryFooterSummaryItems0GetText(Sen......
  • QFramework v1.0 使用指南 工具篇:15. 补充内容:GridKit 二维格子数据结构
    在做游戏的过程中,我们经常需要处理二维格子类的数据,比如消除类游戏、俄罗斯方块、各种棋类游戏,还有我们最常用的Tilemap的地块数据,这些都需要二维格子数据结构。而在Ga......
  • 11G RAC环境GRID目录及文件错误权限的修复
    111.2.0.4环境测试1.1 测试前的资源状态下面查看一下测试前的资源状态,确保每个资源的状态都是正常的。[grid@rac112042~]$crsctlstatusresource-t-----------------......
  • 11G RAC环境GRID目录及文件错误权限的修复
    最近一段时间,遇到几个项目由于种种原因导致GRID_HOME目录或者下面的文件的权限被修改,出现CRS不能正常的启动。在启动ora.mdnsd的时,一直在STARTING。此故障原来模拟过几次都......
  • GridView 自定义简单操作
    usingSystem;usingSystem.Data;usingSystem.Configuration;usingSystem.Collections;usingSystem.Web;usingSystem.Web.Security;usingSy......
  • CSS高级篇——媒体查询 (Media Queries)
    我们已经知道,​​@media​​用于指定特定的媒介,比如screen,print。本篇要介绍的特性在指定媒介的基础上更进一步,可以精确到屏幕尺寸。这也是响应式(responsive)布局的基......
  • GridView的簡單使用
    GridView的簡單使用  項目GitHub地址:https://github.com/leonInShanghai/IMbobo     GridViewXML佈局: <?xmlversion="1.0"encoding="utf-8"?><Li......