http://poj.org/problem?id=1399

http://acm.hit.edu.cn/hoj/problem/view?id=1037

题意:

在一个最多200*200的minecraft方块地图上(由很多1*1*1的方块搭起来的地图,最高5000),其中两块分别有高0.5米的激光塔,有一个高0.5米的机器人要从其中一个激光塔走到另一个。要求只能走相邻4个方向,每次不能爬上超过1格或跳下超过3格(咦,好像真的很像minecraft),要求每走到一个格子,机器人站在在这个格子的中心,能直接接收到至少一个激光塔照射(机器人的头顶与激光塔的顶部连成的直线没有被地形挡住)。

还有就是,地形有缝隙,例如:

1 9

9 1

这样的2*2的地图,在两个高度为1的地形上是可以互相接收到激光的,因为两个9之间有条缝。

题解:

宽搜走路,难点在于判断一格是否能走。

最关键的函数:判断两个格子A、B之间是否被挡。

可分为两部分判断:

1.以x轴为基准,x=Ax,x=Ax+1,x=Ax+2……x=Bx。针对每个x,计算得出浮点数Y(由激光在地平面上的斜率计算得到),可以通过floor(向下取整)得到整数y,得到激光经过(x,y) 和(x+1, y)两个格子之间的交界处,通过这两个格子的高度和激光当时的高度(由激光在竖直切面的斜率计算得到),判断是否被遮挡。

2.以y轴为基准,同上。

上面只说了没有通过缝隙的情况。若发现Y为整数,则是通过了缝隙,在x为轴的情况下,此时改为判断(x,floor(Y-0.5p))和(x+1,floor(Y+0.5p)),p为1或-1,与地平面斜率同号。以y为轴类似。

这个函数写对了其他就简单了。

-------------------------------------------------------------------

这题就难在判断光线可见,建议解题时画出平面图,写出代数公式,研究各种情况的通用判断方法。

程序过不了样例,就调试观察判断激光可见的过程,找到错误。

我写的时候出的错主要在x轴y轴分类讨论有问题、对缝隙情况判断有问题。

代码见下,我写得屁滚尿流,有很多地方有简化得更加清晰明了的余地,仅供参考

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define RD(x) scanf("%d",&x)
#define REP(i,n) for(i=0;i<n;i++)
const int MAXN=;
const int g[][]= {{,,,-},{-,,,}};
const double eps=1e-;
int n,m;
int a[MAXN][MAXN];
int p[][];
bool visited[MAXN][MAXN];
int seeChecked[MAXN][MAXN];
bool ok(int now[], int next[]) {
int y=next[], x=next[];
int h1=a[now[]][now[]];
int h2=a[next[]][next[]];
if(x< || y< || x>=n || y>=m)return false;
if(h2-h1> || h1-h2>)return false;
return true;
} bool canSee2Dot(int x1,int y1,int x2,int y2) {
bool re=true;
int k;
int p[][];
p[][]=x1;
p[][]=y1;
p[][]=x2;
p[][]=y2;
// printf("(%d,%d)->(%d,%d)\n",x1,y1,x2,y2);
REP(k,) {
int st0=p[][k],ed0=p[][k];
int st1=p[][k^], ed1= p[][k^];
if(st0==ed0)continue;
if(ed0<st0) {
swap(ed0,st0);
swap(ed1,st1);
}
// printf("k=%d,%d->%d\n",k,st0,ed0);
double kk=ed1-st1;
kk/=ed0-st0;
double hk=a[ed0][ed1] - a[st0][st1];
if(k==)hk=a[ed1][ed0]-a[st1][st0];
hk/=ed0-st0;
double now = st1 + 0.5 + 0.5*kk;
double nowh = a[st0][st1] + 0.5 + 0.5 * hk;
if(k==)nowh = a[st1][st0] + 0.5 + 0.5*hk;
// printf("%d,%d,%f,%f\n",st0,st1,hk,nowh);
for(int i=st0; i<ed0; i++) {
int theNow = floor(now);
int theX,theY;
double theH1,theH2;
if(fabs(now-round(now))>eps) {
if(k==) {
theX=i;
theY=theNow;
theH1=a[theX][theY];
theH2=a[theX+][theY];
} else {
theX=theNow;
theY=i;
theH1=a[theX][theY];
theH2=a[theX][theY+];
}
// printf("%d,%d,%f,%f,%f,(%f)\n",theX,theY,theH1,theH2,nowh,now); } else {
if(k==) {
theX=i;
theY=floor(now-0.5*fabs(kk)/kk);
theH1=a[theX][theY];
theH2=a[theX+][(int)floor(now+0.5*fabs(kk)/kk)];
} else {
theX=floor(now-0.5*fabs(kk)/kk);
theY=i;
theH1=a[theX][theY];
theH2=a[(int)floor(now+0.5*fabs(kk)/kk)][theY+];
}
// printf("%d,%d,%f,%f,%f,(%f)\n",theX,theY,theH1,theH2,nowh,now);
}
if(theH1>nowh || theH2>nowh) {
re=false;
break;
}
now+=kk;
nowh+=hk;
}
if(!re)break;
}
return re;
} bool canSee(int d[]) {
int x=d[], y=d[];
if(seeChecked[x][y]!=-)return seeChecked[x][y];
bool re=canSee2Dot(x,y,p[][],p[][]) || canSee2Dot(x,y,p[][],p[][]);
seeChecked[x][y]=re;
return re;
}
int farm() {
int b[MAXN*MAXN][];
int bl=,br=;
int i;
if(p[][]==p[][] && p[][]==p[][])return ;
memset(visited,,sizeof(visited));
memset(seeChecked,-,sizeof(seeChecked));
b[][]=p[][];
b[][]=p[][];
while(bl<br) {
int now[];
now[]=b[bl][];
now[]=b[bl][];
now[]=b[bl][];
// printf("now(%d,%d)\n", now[0],now[1]);
bl++;
REP(i,) {
int next[];
next[] = now[]+g[][i];
next[] = now[]+g[][i];
next[] = now[]+;
if(!visited[next[]][next[]] && ok(now,next) && canSee(next)) {
if(next[]==p[][] && next[]==p[][])return next[];
b[br][]=next[];
b[br][]=next[];
b[br][]=next[];
br++;
visited[next[]][next[]]=true;
}
}
}
return -;
} int main() {
int T,i,j;
int x;
RD(T);
while(T--) {
scanf("%d%d",&n,&m);
REP(i,n)REP(j,m)RD(a[i][j]);
scanf("%d%d%d%d",&p[][],&p[][], &p[][], &p[][]);
p[][]--;
p[][]--;
p[][]--;
p[][]--;
x = farm();
if(x!=-)printf("The shortest path is %d steps long.\n",x);
else printf("Mission impossible!\n");
}
return ;
}

poj1399 hoj1037 Direct Visibility 题解 (宽搜)的更多相关文章

  1. [NOIP2002] 字串变换 宽搜+深度优化

    这道题硬是让我用STL水过.......而且题解里说的什么双向宽搜,交替扩展............... 这道题反正,STL用就用吧,但是状态数可以卡到千亿级别,因为这个东西是阶乘扩展的,然后我们发 ...

  2. 利用深搜和宽搜两种算法解决TreeView控件加载文件的问题。

    利用TreeView控件加载文件,必须遍历处所有的文件和文件夹. 深搜算法用到了递归. using System; using System.Collections.Generic; using Sy ...

  3. POJ1426 Find The Multiple (宽搜思想)

    Find The Multiple Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 24768   Accepted: 102 ...

  4. Colorado Potato Beetle(CF的某道) & 鬼畜宽搜

    题意: 一个人在一张大图上走,给你路径与起点,求他走出的矩形面积并.(大概这个意思自行百度标题... SOL: 与其说这是一道图论题不如说是一道生动活泼的STL-vector教学.... 离散化宽搜, ...

  5. BZOJ_1615_[Usaco2008_Mar]_The Loathesome_Hay Baler_麻烦的干草打包机_(模拟+宽搜/深搜)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1615 一个主动轮带着一些轮子转,轮子带着轮子转,轮子带着轮子转...一个非主动轮只会被一个轮子 ...

  6. 【宽搜】ECNA 2015 D Rings (Codeforces GYM 100825)

    题目链接: http://codeforces.com/gym/100825 题目大意: 给你一张N*N(N<=100)的图表示一个树桩,'T'为年轮,'.'为空,求每个'T'属于哪一圈年轮,空 ...

  7. 【宽搜】ECNA 2015 E Squawk Virus (Codeforces GYM 100825)

    题目链接: http://codeforces.com/gym/100825 题目大意: N个点M条无向边,(N<=100,M<=N(N-1)/2),起始感染源S,时间T(T<10) ...

  8. 【拓扑】【宽搜】CSU 1084 有向无环图 (2016湖南省第十二届大学生计算机程序设计竞赛)

    题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1804 题目大意: 一个有向无环图(DAG),有N个点M条有向边(N,M<=105 ...

  9. 【图论】【宽搜】【染色】NCPC 2014 A Ades

    题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1787 题目大意: N个点M条无向边(N,M<=200000),一个节点只能有一个 ...

随机推荐

  1. js中取得当前加载的js的src地址

    在很多js框架中看到过,如果要动态加载框架内部的其他js,加载的时候加载的地址经常是一个相对的地址,只能是这样了哦,因为框架根本不知道用此框架的用户,将框架js文件放的具体目录,所以框架中一般会采用如 ...

  2. hibernate 注解 唯一键约束 uniqueConstraints

    @Table 注解包含一个schema和一个catelog 属性,使用@UniqueConstraints 可以定义表的唯一约束. 如果是联合约束就用下面这种 @Table(name="tb ...

  3. 再解java中的String

    今天看到一篇文章中,写了关于java中的String.我看了后,是我从学java来觉得是最好的一篇关于String类的文章.看了这篇文章你就会对String的认识会提高一个层次.故将原作者的文章特意转 ...

  4. logback配置详解1

    一:根节点<configuration>包含的属性: scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true. scanPeriod: 设置监测配置文 ...

  5. android 项目中出现红色感叹号的解决方法

    问题原因]:工程中classpath中指向的包路径错误 [解决办法]:右键项目名称 BuildPath ---> Configure Build Paht...中,然后上面有几个选项卡找到 Li ...

  6. 解决“只能通过Chrome网上应用商店安装该程序”的方法

    摘要 : 最近有些用户反映某个Chrome插件在安装的时候,提示"只能通过Chrome网上应用商店安装该程序",为了解决这一问题,Chrome插件网带来了相关的解决方法. 某些用户 ...

  7. HTML5 -入门 (---css样式-------------(css基础与css选择器)---------------------—)

    ---恢复内容开始--- 一css基础入门与css选择器 CSS英文全拼:cascading style sheet 层叠样式表. 在html中使用:要在head中写style标签,所有样式放在sty ...

  8. Python-05-常用模块

    sys模块 # sys.argv # 在执行程序的时候可以给程序传参数,例如类似执行nginx检测配置文件语法功能的命令, nginx -t # mode_sys.py import sys prin ...

  9. 微信小程序之使用weui.wxss(八)

    [未经作者本人同意,请勿以任何形式转载] 什么是WeUI? WeUI是在遵守微信视觉设计规范下,由官方设计团队为小程序量身定制的基础样式库. 这里把WeUI放到基础篇里,是因为WeUI是官方出品,并且 ...

  10. 经典SQL语句大全

    一.基础 1.说明:创建数据库CREATE DATABASE database-name 2.说明:删除数据库drop database dbname3.说明:备份sql server--- 创建 备 ...