题意:给出n条y=ai*x+bi的直线。对于这些直线,如果存在x使得该直线y大于其他任意一直线,那么这条直线可以被看见,问有多少条直线可以被看见。
做法什么的不讲了,参见:http://blog.csdn.net/ten_three/article/details/12289427 以及 http://blog.sina.com.cn/s/blog_7eee8bf3010136d8.html
利用了堆栈来做,总体复杂度O(nlogn)
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> using namespace std; #define N 5006 struct node { double x,y; }p[N],line[N]; node stk[N]; int cmp(node ka,node kb) { if(ka.x == kb.x) return ka.y < kb.y; return ka.x < kb.x; } double calc(node ka,node kb) { double res = (ka.y-kb.y)*1.0/(kb.x-ka.x); return res; } int main() { int t,m,n,k; double now,pre; int i,j; int tail; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); sort(p,p+n,cmp); k = 0; for(i=0;i<n-1;i++) { if(p[i].x != p[i+1].x) line[k++] = p[i]; } line[k++] = p[n-1]; if(k < 2) { printf("%d\n",k); continue; } tail = 0; stk[tail++] = line[0]; stk[tail++] = line[1]; pre = calc(stk[1],stk[0]); int ans = 2; for(i=2;i<k;i++) { now = calc(line[i],stk[tail-1]); while(now <= pre) { tail--; if(tail >= 2) { pre = calc(stk[tail-1],stk[tail-2]); now = calc(line[i],stk[tail-1]); } else { now = calc(line[i],stk[tail-1]); break; } } stk[tail++] = line[i]; pre = now; } printf("%d\n",tail); } return 0; }
ZOJ 3967 Colorful Rainbows --栈的应用
时间: 2024-10-11 19:51:04