此题是会员专属,英文版题目链接1274. Number of Ships in a Rectangle

(This problem is an interactive problem.)Each ship is located at an integer point on the sea represented by a cartesian plane,and each integer point may contain at most 1 ship.You have a function Sea.hasShips(topRight, bottomLeft) which takes two points as arguments and
returns true If there is at least one ship in the rectangle represented by the two points, including
on the boundary.Given two points: the top right and bottom left corners of a rectangle, return the numberof ships present in that rectangle. It is guaranteed that there are at most 10 ships in that rectangle.Submissions making more than 400 calls to hasShips will be judged Wrong Answer.
Also, any solutions that attempt to circumvent the judge will result in disqualification.

Example :


Input:
ships = [[1,1],[2,2],[3,3],[5,5]], topRight = [4,4], bottomLeft = [0,0]
Output: 3
Explanation: From [0,0] to [4,4] we can count 3 ships within the range.Constraints:On the input ships is only given to initialize the map internally. You must solvethis problem "blindfolded". In other words, you must find the answer using the given hasShips API, without knowing the ships position.
·0 <= bottomLeft[0] <= topRight[0] <= 1000
·0 <= bottomLeft[1] <= topRight[1] <= 1000
·topRight != bottomLeft

优化前的方法:

很容易想到的方法是把一个矩形四分,然后对每一部分再进行划分,直到只剩一个点,然后判断这个点上是否有船。 这里不必担心超出题目所给的函数调用400次的限制条件,因为船只数量限定在10个。
但是会出现重复计算的问题,比如中间的一个点会在划分的四个子矩形内个被计算一次,总共是四次,而端点只会被计算一次,边上的点(非端点)会被计算两次,为了得到正确答案,我们在判断某个点上是否有船的时候还需判断这个点的位置——在端点返回4,在边上返回2,在中心返回1, 这样最后得到的结果除以4就可以得到正确结果。
/*** // This is Sea's API interface.* // You should not implement it, or speculate about its implementation* class Sea {*   public:*     bool hasShips(vector<int> topRight, vector<int> bottomLeft);* };*/class Solution {public:vector<int> inittop, initbottom;bool online(vector<int> pos){if(pos[0] == inittop[0] || pos[0] == initbottom[0] || pos[1] == inittop[1] || pos[1] == initbottom[1])return true;return false;}//判断是否在边界bool onpron(vector<int> pos){if((pos[0] == inittop[0] || pos[0] == initbottom[0])&& (pos[1] == inittop[1] || pos[1] == initbottom[1]))return true;return false;} //判断是否在顶点int countShips1(Sea sea, vector<int> topRight, vector<int> bottomLeft) {//四分if(topRight[0] == bottomLeft[0] && topRight[1] == bottomLeft[1]) {if(!sea.hasShips(topRight,bottomLeft)) return 0;if(onpron(bottomLeft))return 4;else if(online(bottomLeft))return 2;elsereturn 1;}if(!sea.hasShips(topRight, bottomLeft))return 0;int sum = 0;int x = (topRight[0] + bottomLeft[0])/2;int y = (topRight[1] + bottomLeft[1])/2;if(x == bottomLeft[0]){if(y == bottomLeft[1]){sum += countShips1(sea, bottomLeft, bottomLeft);sum += countShips1(sea, topRight, topRight);sum += countShips1(sea,vector<int>({bottomLeft[0],topRight[1]}),vector<int>({bottomLeft[0],topRight[1]}));sum += countShips1(sea,vector<int>({topRight[0],bottomLeft[1]}), vector<int>({topRight[0],bottomLeft[1]}));}else{sum += countShips1(sea, topRight, vector<int>({x, y}));//2sum += countShips1(sea, vector<int>({topRight[0], y}), vector<int>({x, bottomLeft[1]}));//4}}else{if(y == bottomLeft[1]){sum += countShips1(sea, vector<int>({x, topRight[1]}), vector<int>({bottomLeft[0], y}));//1sum += countShips1(sea, topRight, vector<int>({x, y}));//2}else{sum += countShips1(sea, vector<int>({x, topRight[1]}), vector<int>({bottomLeft[0], y}));//1sum += countShips1(sea, vector<int>({topRight[0], y}), vector<int>({x, bottomLeft[1]}));//4sum += countShips1(sea, vector<int>({x, y}), bottomLeft);//3sum += countShips1(sea, topRight, vector<int>({x, y}));//2}}return sum;}int countShips(Sea sea, vector<int> topRight, vector<int> bottomLeft) {inittop = topRight;initbottom = bottomLeft;return countShips1(sea, topRight, bottomLeft)/4;}
};

优化后的方法

上述解法还涉及到对边长为1的矩形的划分问题,实在是过于麻烦,然后我在提交中看到了大佬8ms的解法——把一个矩形拆分成左下的一个子矩形,上方的一条直线,右边的一条直线和右上角的一个点。 这样避免了点被重复判断的问题。
class Solution {private:int search(Sea &sea, int top, int right, int bottom, int left) {if (top == bottom && right == left) {return sea.hasShips(vector<int>{top, right}, vector<int>{bottom, left});} else {int midv = (top + bottom) / 2, midh = (left + right) / 2;int result = 0;if (sea.hasShips(vector<int>{midv, midh}, vector<int>{bottom, left})) {result += search(sea, midv, midh, bottom, left);}if (midv < top && sea.hasShips(vector<int>{top, midh}, vector<int>{midv + 1, left})) {result += search(sea, top, midh, midv + 1, left);}if (midh < right && sea.hasShips(vector<int>{midv, right}, vector<int>{bottom, midh + 1})) {result += search(sea, midv, right, bottom, midh + 1);}if (midv < top && midh < right &&sea.hasShips(vector<int>{top, right}, vector<int>{midv+1, midh+1})) {result += search(sea, top, right, midv + 1, midh + 1);}return result;}}
public:int countShips(Sea sea, vector<int> topRight, vector<int> bottomLeft) {return search(sea, topRight[0], topRight[1], bottomLeft[0], bottomLeft[1]);}
};

<leetcode c++>1274. Number of Ships in a Rectangle相关推荐

  1. <LeetCode天梯>Day004 买卖股票的最佳时机 II(DP动态规划法) | 初级算法 | Python

    今天1024程序员节,车神哥在这里恭祝各位节日快乐,发量惊人,财务自由,从不加班!!!~ 今天依旧和车神哥一起来提升自己的Python编程和面试能力吧,刷天梯~ 以下为我的天梯积分规则: 每日至少一题 ...

  2. <LeetCode天梯>Day043 Fizz Buzz(按部就班) | 初级算法 | Python

  3. <Linux开发>驱动开发 -之-platform 驱动

    <Linux开发>驱动开发 -之-platform 驱动 交叉编译环境搭建: <Linux开发> linux开发工具-之-交叉编译环境搭建 uboot移植可参考以下: < ...

  4. c语言switch虚线,有以下程序:include<stdio.h>main(){int c;while((c=getchar())!='\n')switch(c-'2'){case 1:pu...

    有以下程序:include<stdio.h>main(){int c:while((c=getchar())!='\n')switch(c-'2'){case 1:pu 更多相关问题 双代 ...

  5. List<Map<String, Object>>——多层嵌套的数据结构

    文章目录 快速理解多重嵌套结构 Map基础知识 List 例子 查询数据库 快速理解多重嵌套结构 对于多层嵌套的数据结构,需要层层分解. 以List<Map<String, Object& ...

  6. leetcode 321 Create Max Number

    leetcode 321 Create Max Number greedy的方法,由于有两个数组,我们很自然的想到从数组1中选i个数,数组2中选k-i个数,这样我们只需要遍历max(0, k-数组2长 ...

  7. <Linux开发> ubuntu开发工具-Ubuntu测试网速及实时网速图

    <Linux开发> ubuntu开发工具-Ubuntu测试网速及实时网速图 一.查看网线上行.下行网速 1.安装speedtest-cli工具 water@water-Tower-PC:~ ...

  8. Python房价分析和可视化<anjuke二手房>

    Python房价分析和可视化<anjuke二手房> 本文是Python数据分析实战的房价分析系列,本文分析二线城市贵阳的二手房. 数据获取 本文的数据来源于2022年7月anjuke的二手 ...

  9. Spring 事务源码(2)—<tx:annotation-driven/>事务标签源码解析

      基于最新Spring 5.x,详细介绍了Spring 事务源码,包括< tx:annotation-driven/>标签源码解析.   此前我们已经学习了Spring的<tx:a ...

最新文章

  1. Spring Bean四种注入方式(Springboot环境)
  2. java反射的性能_java反射的性能问题
  3. Tomcat在修改代码后不会自动reload解决办法
  4. Mysql存储过程名规则_sql 存储过程命名规范
  5. 先知模型 facebook_Facebook先知
  6. 程序员如何自我超越,教你一招
  7. InfluxDB Java入门
  8. VisualTreeHelper
  9. 计算机关机电路,实用电脑电源关机全断电电路
  10. HTML5权威指南pdf
  11. 机器学习深度学习入门学习资料大全(一)
  12. android检测cup温度工具,Android如何实现获取手机CPU的温度?
  13. 利用武汉理工大学学校图书馆资源查论文 以使用中国知网查阅论文
  14. aip通用文档 服务器,为 Rights Management 连接器配置服务器 - AIP | Microsoft Docs
  15. 安卓如何调出软键盘_Android软键盘-显示隐藏软键盘
  16. LeetCode——跳跃游戏
  17. SURF C++代码 详细阅读(二)—— 极值点检测 确定极值点精确位置
  18. 关于运算放大器电流流向的问题
  19. 臭鱼的产品交互设计分享
  20. 网络训练时出现loss为nan的情况(已解决)

热门文章

  1. ai切换rgb模式_怎么更改ai的cmyk模式?ai里怎么更改cmyk模式?
  2. 卡巴斯基报告:2019年前全球有19%的人购买了加密货币
  3. 唯品会电商销售复盘分析
  4. css 清除浮动的几种方式
  5. 天玑810和骁龙695哪个好 天玑810和骁龙695差别
  6. 大学计算机科技论文格式,大学生论文格式及范文
  7. 剑网三的哪个服务器是最新的,横向对比剑网3怀旧服有多良心?这三点区别你要知道!...
  8. 设计模式-创建型模式-简单工厂模式
  9. 在张小龙身上,我看到了「失控」的影子
  10. 基于MDKA5D31-EK_T70开发板的QT示例-demo03:WeatherDate