【计算几何】ZOJ 2967 Colorful Rainbows
2014-02-24 19:41
441 查看
以下为摘抄的讲解:
给定直线,对每条直线,传说解不等式组可以过,直接看是否存在一个点在直线之上。(左端点取max,右端点取min,如果左>=右,直接break掉)。有点ft...O(n^2) n=5000 rp好的可以过....
我用的方法类似于凸包,先把所有直线按照斜率a由小到大排序,斜率相同取b较大的,扔掉b小的。于是所有直线斜率不同。准备一个栈,栈里面存放上一次能看到的“最上面”的直线以及这条直线能看到的范围x(x值右边的部分可以被看到)。初始时,把斜率最小的直线入栈,并记录x值为-inf。然后对第i条直线,所做的是用第i条直线和栈顶直线求交点x,如果这个x值不大于栈顶的x值,则把栈顶元素弹出,继续求交,否则退出。这种判断操作直到栈为空,或者当前栈顶的x值大于栈顶的x值。然后把第i条直线入栈,继续,看后面的直线。最后栈中的直线数就是能看到的。这种做法类似于凸包的方法,除去排序外,每条直线至多出入栈一次,复杂度O(n)。总复杂度是O(nlogn)。
看了讲解,自己写了代码,A的有点虐心。。。
最后时间100ms,算是中等的耗时。。。
给定直线,对每条直线,传说解不等式组可以过,直接看是否存在一个点在直线之上。(左端点取max,右端点取min,如果左>=右,直接break掉)。有点ft...O(n^2) n=5000 rp好的可以过....
我用的方法类似于凸包,先把所有直线按照斜率a由小到大排序,斜率相同取b较大的,扔掉b小的。于是所有直线斜率不同。准备一个栈,栈里面存放上一次能看到的“最上面”的直线以及这条直线能看到的范围x(x值右边的部分可以被看到)。初始时,把斜率最小的直线入栈,并记录x值为-inf。然后对第i条直线,所做的是用第i条直线和栈顶直线求交点x,如果这个x值不大于栈顶的x值,则把栈顶元素弹出,继续求交,否则退出。这种判断操作直到栈为空,或者当前栈顶的x值大于栈顶的x值。然后把第i条直线入栈,继续,看后面的直线。最后栈中的直线数就是能看到的。这种做法类似于凸包的方法,除去排序外,每条直线至多出入栈一次,复杂度O(n)。总复杂度是O(nlogn)。
看了讲解,自己写了代码,A的有点虐心。。。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <stdlib.h> #include <algorithm> using namespace std; int n, line_num; struct Line { double k, b; } l[5010]; bool cmp(struct Line u, struct Line v) { return u.k<v.k; } void jiaodian(Line aa, Line bb, double& x) { x = (bb.b - aa.b) / (aa.k - bb.k); } int isexit(double hh) { for(int i = 0; i < line_num; i ++) if(l[i].k == hh) return i; return -1; } void solve() { int cnt = 1,dian = 0, xx[5000] = {0}; double jd[5010] = {0.0}, temp; xx[0] = 0; for(int i = 1; i < line_num; i++) { while(1) { jiaodian(l[xx[cnt - 1]], l[i], temp); if((temp > jd[dian - 1] && dian >= 1) || cnt == 1) { jd[dian ++] = temp; xx[cnt ++] = i; break; } else { cnt --; dian --; } } } printf("%d\n", cnt); } int main() { int cas; double hh, ll; scanf("%d", &cas); while(cas--) { line_num = 0; scanf("%d", &n); for(int i = 0; i < n; i ++) { scanf("%lf%lf", &hh, &ll); int tee = isexit(hh); if(tee == -1) { l[line_num].k = hh; l[line_num].b = ll; line_num++; } else if(l[tee].b < ll) { l[tee].b = ll; } } sort(l, l+line_num, cmp); solve(); } return 0; }
最后时间100ms,算是中等的耗时。。。
相关文章推荐
- 仿SGI STL的traits技法
- 转:async & await 的前世今生 ; 异步 线程 多线程
- Mac rails console database error
- [问题】Command /Developer/usr/bin/ibtool failed with exit code 255 error ?
- 使用git error: RPC failed; result=22, HTTP code = 411
- 使用git error: RPC failed; result=22, HTTP code = 411
- What are training set, validation set and test set?
- leetcode:Container With Most Water
- RIAD介绍之raid搭建
- Shiro-1.2.2内置的FilterChain
- [ACM] hdu 1022 Train Problem I(栈的使用)
- [ACM] hdu 1022 Train Problem I(栈的使用)
- IBATIS 保存的时间类型为空的配置方式 isPropertyAvailable
- Chapter 6 笔记 智力题 Brain Teasers
- Mongodb源码分析--主程序入口main()
- 谷歌人工智能大师:未来的机器将比人类更聪明
- H264参数语法文档: SPS、PPS、IDR( http://blog.csdn.net/heanyu/article/details/6205390)
- 揭晓2014 Jolt Awards编码工具 JetBrains等榜上有名
- 线程的sleep和wait的区别
- 从 varchar 数据类型到 datetime 数据类型的转换产生一个超出范围的值/Conversion failed when converting date and/or time from c