织梦 两个网站应用市场下载安装软件
织梦 两个网站,应用市场下载安装软件,系统开发与网站开发,wordpress 手机号登录【问题描述】 小明每天都要练功#xff0c;练功中的重要一项是梅花桩。 小明练功的梅花桩排列成 n 行 m 列#xff0c;相邻两行的距离为 1#xff0c;相邻两列的距离也为 1。 小明站在第 1 行第 1 列上#xff0c;他要走到第 n 行第 m 列上。小明已经练了一段时间#xff… 【问题描述】 小明每天都要练功练功中的重要一项是梅花桩。 小明练功的梅花桩排列成 n 行 m 列相邻两行的距离为 1相邻两列的距离也为 1。 小明站在第 1 行第 1 列上他要走到第 n 行第 m 列上。小明已经练了一段时间他现在可以一步移动不超过 d 的距离直线距离。 小明想知道在不掉下梅花桩的情况下自己最少要多少步可以移动到目标。 【输入格式】 输入的第一行包含两个整数 n, m分别表示梅花桩的行数和列数。 第二行包含一个实数 d最多包含一位小数表示小明一步可以移动的距离。 【输出格式】 输出一个整数表示小明最少多少步可以到达目标。 【样例输入】 3 4 1.5 【样例输出】 3 【评测用例规模与约定】 对于 30% 的评测用例2 n, m 201 d 20。 对于 60% 的评测用例2 n, m 1001 d 100。 对于所有评测用例2 n, m 10001 d 100。 思路根据题意可以采用广度优先搜索将遍历过的点加入到一个队列队列中的点距原点1,1的距离从小到大每次从队首中取出结点进行拓展直至拓展至终点。
要解决的问题
①如何判断到达每个点的最小步数用一个二维数组vis存储vis[i][j]表示1,1到i
j的最小步数从ij拓展出点st则令vis[s][t]vis[i][j]1也就是步数加1
②如何拓展周围的点读懂题目的值只要我一步的距离小于d我去哪都行直着走也行斜着走也行就像是以点ij为圆心做半径为d的圆圆里边的点我都可以拓展。那怎么判断哪些点在圆内呢可以用两层for循环来遍历然后判断那些点与圆心的距离是否小于d来判断是否在圆内。不过这样时间复杂度就有点大了可以贪心一下如下图 那怎么找一水平线最大能像右边拓展的点呢用二分从一堆与圆形距离小于等于d的点中找最大那个
③通过上述思路可以写出来代码但是还是有一个测试点显示时间超时那怎么优化呢
可以想到我们用一个点拓展出的其他点步数都是一样的那我只取距离终点nm最近的那个放入队列再进行拓展不就好了
好了问题应该就这些了ac代码如下
#includebits/stdc.h
using namespace std;
int vis[1010][1010];
int n,m;
double d;
struct Point {int x,y;
};
double dis(int x1,int y1,int x2,int y2) {return sqrt(pow(x1-x2,2)pow(y1-y2,2));
}
int bfs() {queuePointq;q.push({1,1});vis[1][1]1;while(!q.empty()) {Point pq.front();q.pop();if(d-dis(n,m,p.x,p.y)-1e-6)return vis[p.x][p.y];//不用到终点我只需要知道在某个点能不能一步到终点即可如果能到我直接得出结果为什么这里不用加1因为我的步数是从1开始的所以自然多了一个1int x11,y11;double minDis0x3f3f3f3f;for(int ip.x; imin(p.xd,n*1.0); i) {//二分找y的最大值int mid;int lp.y,rmin(m*1.0,p.yd);while(lr) {mid(lr1)/2;if(d-dis(p.x,p.y,i,mid)-1e-6)lmid;else rmid-1;}if(!vis[i][l]minDisdis(i,l,n,m)) {x1i,y1l,minDisdis(i,l,n,m);}}if(!vis[x1][y1]){//只拓展离终点最近的那个q.push({x1,y1});vis[x1][y1]vis[p.x][p.y]1;}}return -1;
}
int main() {cinnm;cind;coutbfs()endl;
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/91258.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!