题意:求解凸包和凸包上两点间共线的点
#include<cmath>
#include<math.h>
#include<cstdio>
#include<iostream>
#include <string.h>
#include <algorithm>
using namespace std;
# define eps 1e-8
#define maxn 5555
struct point
{
int x,y,v;
int id;
point(double x=0,double y=0):x(x),y(y){}
bool operator==(point const&a)const{
return x==a.x&&y==a.y;
}
bool operator<(point const&a)const{
return x<a.x||(x==a.x&&y<a.y);
}
point operator-(point a){
return point(x-a.x,y-a.y);
}
}po[maxn],stack[maxn],p[maxn];
int top,k;
bool cmpx(point a,point b) //找最右边的点
{
if(a.x==b.x)
return a.y<b.y;
else
return a.x<b.x;
}
bool cmp(point a,point b){
return a.v>b.v;
}
//叉积,结果大于0表示向量p0p1的极角小于p0p2的极角,等于则两向量共线
int multi(point p1, point p2, point p0)
{
return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
int cmp1(point a,point b) //用于排序操作
{
double k=multi(a,b,po[0]);
if(fabs(k)<eps) //减少精度误差,计算几何的特点,精度要求高
return a.x<b.x;
return k>0;
}
int Cross (point a ,point b){
return b.y*a.x-a.y*b.x;
}
int dotDet(point a,point b){
return a.x*b.x+a.y*b.y;
}
bool Gongxian(point x,point a,point b){
return (Cross(a-x,b-x)==0)&&dotDet(a-x,b-x)<=0||a==x||b==x;
}
int ConvexHull(point *p,int n,point *ch){
sort(p,p+n);
int m=0;
for(int i=0;i<n;i++){
while(m>1&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0)m--;
ch[m++]=p[i];
}
int k=m;
for(int i=n-2;i>=0;i--){
while(m>k&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0)m--;
ch[m++]=p[i];
}
if(n>1)m--;
return m;
}
int ans[maxn],x[maxn],y[maxn],mp[555][555];
int xcnt,ycnt,same;
double mmi;
int main(){
int n,_=0;
while(~scanf("%d",&n)){
if(n==0)break;
mmi=0,same=0,xcnt=0,ycnt=0;
memset(ans,0,sizeof ans);
memset(mp,0,sizeof mp);
for(int i=0;i<n;++i){
scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].v);
x[xcnt++]=p[i].x,y[ycnt++]=p[i].y;
p[i].id=i;
if(i==0){
mmi=p[i].v;
}else if(p[i].v>mmi){
same=0;
mmi=p[i].v;
}else if(p[i].v==mmi){
same++;
}
}
printf("Case #%d: ",++_);
if(mmi==0){
for(int i=0;i<n;++i)printf("0");
printf("\n");
continue;
}
sort(p,p+n,cmp);
sort(x,x+n);
sort(y,y+n);
xcnt=(int)(unique(x,x+n)-x);
ycnt=(int)(unique(y,y+n)-y);
memset(mp,0,sizeof mp);
int all=0;
for(int i=0;i<=same;++i){
int xx=(int)(lower_bound(x,x+xcnt,p[i].x)-x);
int yy=(int)(lower_bound(y,y+ycnt,p[i].y)-y);
if(p[i].v==mmi){
if(!mp[xx][yy]){
po[all].x=p[i].x;
po[all].y=p[i].y;
po[all++].id=p[i].id;
}
mp[xx][yy]++;
}
}
if(all==1||all==2){
for(int i=0;i<=same;++i){
int xx=(int)(lower_bound(x,x+xcnt,p[i].x)-x);
int yy=(int)(lower_bound(y,y+ycnt,p[i].y)-y);
if(mp[xx][yy]==1){
ans[p[i].id]=1;
}
}
}
// /*
top=ConvexHull(po,all,stack);
for(int i=0;i<top;++i){
int xx=(int)(lower_bound(x,x+xcnt,stack[i].x)-x);
int yy=(int)(lower_bound(y,y+ycnt,stack[i].y)-y);
if(mp[xx][yy]==1)ans[stack[i].id]=1;
}
for(int i=0;i<top;++i)
for(int j=0;j<n;++j){
int xx=(int)(lower_bound(x,x+xcnt,p[j].x)-x);
int yy=(int)(lower_bound(y,y+ycnt,p[j].y)-y);
if(p[j].v==mmi&&mp[xx][yy]==1){
if(Gongxian(p[j],stack[i],stack[(i+1)%top]))
ans[p[j].id]=1;
}
}
//*/
/*
if(all>=3){
k=-1;
for(int i=0;i<all;i++){
if(k==-1||cmpx(po[i],po[k]))
k=i;
}
swap(po[0],po[k]);
top=2;
sort(po+1,po+all,cmp1);
stack[0]=po[0],stack[1]=po[1],stack[2]=po[2];
for(int i=3;i<all;i++){
while(top>1&&multi(po[i],stack[top],stack[top-1])>=0)// = X
top--;
stack[++top]=po[i];
}
top++;
// printf("%d\n",top);
for(int i=0;i<top;++i){
int xx=(int)(lower_bound(x,x+xcnt,stack[i].x)-x);
int yy=(int)(lower_bound(y,y+ycnt,stack[i].y)-y);
if(mp[xx][yy]==1)ans[stack[i].id]=1;
}
for(int i=0;i<top;++i)
for(int j=0;j<n;++j){
int xx=(int)(lower_bound(x,x+xcnt,p[j].x)-x);
int yy=(int)(lower_bound(y,y+ycnt,p[j].y)-y);
if(p[j].v==mmi&&mp[xx][yy]==1){
if(onSeg(p[j],stack[i],stack[(i+1)%top]))
ans[p[j].id]=1;
}
}
}
*/
for(int i=0;i<n;++i)printf("%d",ans[i]);
printf("\n");
}
return 0;
}