http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2967
首先斜率相同去个重 然后单调栈维护每条直线和之前可见直线的交点及自身斜率和截距 对于新加直线 看于栈顶直线的交点位置即可
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#include <cmath>
using namespace std;
const double eps=1e-10;
const int maxn=8e3+10;
struct node
{
double k,b,p;
};
stack <node> stk;
node line[maxn];
int n;
bool cmp(node n1,node n2)
{
if(fabs(n1.k-n2.k)<eps) return n1.b>n2.b;
else return n1.k<n2.k;
}
int main()
{
node cur,tmp;
double pos;
int t,i,j;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%lf%lf",&line[i].k,&line[i].b);
}
sort(line+1,line+n+1,cmp);
j=0;
for(i=1;i<=n;i++){
if(j==0||fabs(line[j].k-line[i].k)>eps){
line[++j]=line[i];
}
}
n=j;
if(n==1){
printf("1\n");
continue;
}
while(!stk.empty()) stk.pop();
tmp.k=line[1].k,tmp.b=line[1].b,tmp.p=0;
stk.push(tmp);
tmp.k=line[2].k,tmp.b=line[2].b,tmp.p=(line[2].b-line[1].b)/(line[1].k-line[2].k);
stk.push(tmp);
for(i=3;i<=n;i++){
while(stk.size()>1){
cur=stk.top();
pos=(line[i].b-cur.b)/(cur.k-line[i].k);
if(cur.p>pos||fabs(cur.p-pos)<eps) stk.pop();
else{
tmp.k=line[i].k,tmp.b=line[i].b,tmp.p=(line[i].b-cur.b)/(cur.k-line[i].k);
stk.push(tmp);
break;
}
}
if(stk.size()==1){
tmp.k=line[i].k,tmp.b=line[i].b,tmp.p=(line[i].b-line[1].b)/(line[1].k-line[i].k);
stk.push(tmp);
}
}
printf("%d\n",stk.size());
}
return 0;
}
/*
1
3
-2 -2
-1 -1
-0.5 -0.5
*/