Prob_Solve 板


LINE

抱歉再利用一篇文章解释这题模糊不清的地方。 题目网址:http://www.spoj.pl/problems/DIRVS/ 对於题目规定的direct visibility,我粗浅的了解如下: 目标点(i1, j1),测试点(i2, j2), 现在只讨论i1 != i2 && j1 != j2的平面两点, 两点的2D连线为两sqare中心点彼此的连线,故连线距离有以下的公式: double calDistance(double y1, double x1, double y2, double x2) { return sqrt((y1 - y2) * (y1 - y2) + (x1 - x2) * (x1 - x2)); } 两点的直线距离代入公式(在此先使用原始算法,不简化同加0.5的可省略): calDistance(i1 + 0.5, j1 + 0.5, i2 + 0.5, j2 + 0.5); 目标点(i1, j1)的高度为2,测试点(i2, j2)的高度为4。 分别标记为h[i1][j1], h[i2][j2], 以目标点为基准点得到3D高度的斜率mh,则有如下的推导: (请注意题目有句half metre above surface,在表面上半公尺,高度也要加0.5) mh = (double)((h[i2][j2] + 0.5) - (h[i1][j1] + 0.5)) / calDistance(i1 + 0.5, j1 + 0.5, i2 + 0.5, j2 + 0.5); 则对於目标点和测试点之间经过的cube,平面座标记为(ip, jp), 如果是取cube中心点来计算,同斜率mh该有的高度hp应该为: (将mh的计算移项推导出来) hp = mh * calDistance(i1 + 0.5, j1 + 0.5, ip + 0.5, jp + 0.5) + (h[i1][j1] + 0.5); 如果h[ip][jp] > hp,则表示被档到视线。 ####这边是疑点1., ####计算是metre above the surface,但挡住视线必须是cube的solid。 这是由经过的cube的中心点计算的,但实际上这视线在3D是以斜线呈现的, 所以上述推导hp的公式如果在平面不是经过(ip, jp)中心点就不能计算中心点, 如果在(i1 + 0.5, j1 + 0.5)和(i2 + 0.5, j2 + 0.5)的2D连线交於 (ip, jp)的点记为(it, jt),则公式要修正: hp = mh * calDistance(i1 + 0.5, j1 + 0.5, it, jt) + (h[i1][j1] + 0.5); 以上是我判断direct visibility的基本认知和公式。 问题就在於如何快速的(it, jt)的计算。 以 row 1 column 5 高度 2 3 4 1 5 从(1, 1)到(1, 3),套入上面的公式。 两点距离基准点(1, 1)的calDistance(1.5, 1.5, 1.5, 3.5) = 2.0 mh = (4.5 - 2.5) / 2.0 = 1.0 我们看高度为3的点(1, 2), 这条视线在左边交於点(1, 2)假设是(1.5, 2.0001),最远的范围(1.5, 2.9999)。 则利用公式计算左边高度应该为3.5001,最远高度应为4.4999。 (以上是假设误差在0.0001,实际上误差是无穷小的) 3.5001 > 3.0 && 4.4999 > 3.0 故这视线不会被档到。 目前问题是1维的很简单,但平面是有难度的。 下面是一个2D的square。 column 2.0 3.0 row 1.0 -------- | | | | | | 2.0 -------- 将上图的要讨论的点标记在下图: (1.0, 2.0) (1.0, 3.0) *--------* | | (1.5, 2.0001)|* | | *|(1.6666, 2.9999) *--------* (2.0, 2.0) (2.0, 3.0) 对於从(1.5, 2.0001)左方穿过square直到(1.6666, 2.9999)的右方 的我的计算方法: #deifne LEFT (1 << 0) #define RIGHT (1 << 1) #define UP (1 << 2) #define DOWN (1 << 3) char touch[205][205]; // 初始化全为0 直线公式 y = mx + b,m和b已经计算出, 则x带入2.0可得y = 1.49999,取整数为1 touch[1][2] |= LEFT; 则x带入3.0可得y = 1.66665,取整数为1 touch[1][2] |= RIGHT; // 3 - 1 = 2 同理UP和DOWN, 我的想法在touch[1][2]有两个以上的标记,就可以判断点(1, 2)是被穿过的。 但是也有一个可能是直线从(1.0, 2.0)穿过(2.0, 3.0) 完全没有标记但有被穿过, 或是(1.0, 2.0)穿过(1.66666, 2.99999), 此时只有RIGHT标记但有被穿过, 所以我又多计算x带入2.5,得y = 1.59999, 只要y是有小数点的,就表示是被穿过的。 如此两道工序来快速判断(it, jt),时间上是允许的, 但是WA,唉,可能还需要多debug,就请观文者给予指导。 对於上面标注的#####疑点,不晓得观文者有没有看法。 谢谢。 Bleed --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 114.43.120.234







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Boy-Girl站内搜寻

TOP