zoukankan      html  css  js  c++  java
  • Leetcode-1001 Grid Illumination(网格照明)

    作者水平有限,所发仅为个人愚见,如有明显谬误,望斧正

    先考虑使用暴力/模拟,观察所给数据范围,N最高可达109,因此模拟必定不可行。观察询问队列的长度和灯队列的长度,因为询问队列一定要遍历一遍,所以由此可想到O(nm)解法(其中n为询问队列长度,m为灯队列长度),即在遍历询问队列的同时,遍历灯队列,如果询问队列的询问点被灯照亮,则在结果数组的相应位置将值置为1,否则为0。当一个询问点结束以后,将此询问点周围的灯熄灭,即从灯队列中删除。

     1 #define pb push_back
     2 #define maxSize 3939
     3 #define _for(i,a,b) for(int i = (a);i < (b);i ++)
     4 
     5 class Solution
     6 {
     7     public:
     8         bool ispang(int x1,int y1,int x2,int y2)
     9         {
    10             return (x1==y1&&x2==y2)
    11             || (x1==x2&&x2==y2-1)
    12             || (x1==x2&&x2==y2+1)
    13             || (x1==x2-1&&x2==y2)
    14             || (x1==x2-1&&x2==y2-1)
    15             || (x1==x2-1&&x2==y2+1)
    16             || (x1==x2+1&&x2==y2)
    17             || (x1==x2+1&&x2==y2-1)
    18             || (x1==x2+1&&x2==y2+1);
    19         }
    20         vector<int> gridIllumination(int N, vector<vector<int>>& lamps, vector<vector<int>>& queries)
    21         {
    22             int qsz = queries.size();
    23             int lsz = lamps.size();
    24             set<pair<int,int>> lamp;
    25             for(int i = 0;i < lsz;i ++)
    26                 lamp.insert({lamps[i][0],lamps[i][1]});
    27             
    28             vector<int> rnt(qsz,0);
    29             
    30             for(int i = 0;i < qsz;i ++)
    31             {
    32                 for(auto j = lamp.begin();j != lamp.end();j ++)
    33                 {
    34                     if(queries[i][0]==j->first||queries[i][1]==j->second
    35                     ||abs(queries[i][0]-j->first)==abs(queries[i][1]-j->second))
    36                     {
    37                         rnt[i] = 1;
    38                         break;
    39                     }
    40                 }
    41                 
    42                 for(auto j = lamp.begin();j != lamp.end();j ++)
    43                 {
    44                     if(ispang(queries[i][0],queries[i][1],j->first,j->second))
    45                     {
    46                         lamp.erase(j);
    47                         break;
    48                     }
    49                 }
    50             }
    51             return rnt;
    52         }
    53 };
    Leetcode-1001(C++)(32/33通过样例)

    那么很显然,在最大数据量情况下,加上常数,需要数十秒左右才能跑完,因此超时。寻求时间复杂度更低的解法,对原程序进行优化。

    但由此我们观察到有以下两点是必须完成的动作:

    ① 对给出询问点的询问操作

    ② 对询问点周围灯的删除操作

    对于②删除操作,可以将pari<int,int>的点对作为set的查询元素,则可以方便的将灯从灯队列中加入或删除,也就是对于删除操作,时间复杂度可以将为O(nlogm)。于是考虑对①询问操作的优化,若将询问操作的时间复杂度也将为O(nlogm),则问题可解。

    查询分为四条:

    ①行的查询

    ②列的查询

    ③主对角线查询

    ④辅对角线查询

    观察到若查询点与灯有同一x,则行相同

    若查询点与灯有同一y,则列相同

    若查询点与灯有同一x-y,则在同一主对角线

    若查询点与灯有同一x+y,则在同一辅对角线

    对灯队列进行预处理,对于每一行,每一列,每一主对角线,每一辅对角线,分别计算有多少个灯在其上,删除时,每删除一个灯,将其照亮区域的相对应行列对角线的灯数量减一,这样查询时如果对于某一行或列或者对角线有灯在其上,也就是这四个查询数组的值只要有一个不为0,则该点一定是被照亮的。由此,题目解决。

     1 #define pb push_back
     2 #define maxSize 3939
     3 #define _for(i,a,b) for(int i = (a);i < (b);i ++)
     4 
     5 int dx[] = {0,1,-1,0,1,-1,0,1,-1};
     6 int dy[] = {-1,-1,-1,0,0,0,1,1,1};
     7 class Solution
     8 {
     9     public:
    10         set<pair<int,int>> s;
    11         map<int,int> cm,rm,dxm,dym;
    12         void add(int x,int y)
    13         {
    14             s.insert({x,y});
    15             cm[x] ++;
    16             rm[y] ++;
    17             dxm[x+y] ++;
    18             dym[x-y] ++;
    19         }
    20         void remove(int x,int y)
    21         {
    22             auto it = s.find({x,y});
    23             if(it==s.end())
    24                 return ;
    25             s.erase(it);
    26             cm[x] --;
    27             rm[y] --;
    28             dxm[x+y] --;
    29             dym[x-y] --;
    30         }
    31         int judge(int x,int y)
    32         {
    33             return cm[x]>0||rm[y]>0||dxm[x+y]>0||dym[x-y];
    34         }
    35         vector<int> gridIllumination(int N, vector<vector<int>>& lamps, vector<vector<int>>& queries)
    36         {
    37             _for(i,0,lamps.size())
    38                 add(lamps[i][0],lamps[i][1]);
    39             
    40             vector<int> rnt;
    41             _for(i,0,queries.size())
    42             {
    43                 rnt.push_back(judge(queries[i][0],queries[i][1]));
    44                 _for(j,0,9)
    45                 {
    46                     int nx = queries[i][0]+dx[j];
    47                     int ny = queries[i][1]+dy[j];
    48                     remove(nx,ny);
    49                 }
    50             }
    51             return rnt;
    52         }
    53 };
    Leetcode-1001(C++)

    执行用时:1200ms

  • 相关阅读:
    SELECT SCREEN 整理2 转载
    SELECT SCREEN 整理1 转载
    ABAP面向对象 转载
    [OO]ABAP OO 语法--实例看 "="与"?=" 的区别[转]
    cl_salv_table
    sapui5 组件重用
    sapui5 使用common(其他工程)的i18n 文件
    sapui5 app之间迁移
    导航与路由10-17(渣翻完结)
    导航与路由1-9 (渣翻)
  • 原文地址:https://www.cnblogs.com/Asurudo/p/10429493.html
Copyright © 2011-2022 走看看