题目意思很无聊, 你可以证明两点。
A、 速度最大的才能到最远点
B、 只有凸包边上的点才能到无穷远点。
然后就是一个无聊的凸包, 人站在一起并且速度相同的要排除掉。
。。被自己这个模板坑死了。 。。后来手动加上判是否在凸包上才过掉。。白浪费了3小时。。
#include #include #include #include #include #include #include #include #include #include #include #include #define mp(x,y) make_pair(x,y) #define pii pair #define pLL pair #define pb(x) push_back(x) #define rep(i,j,k) for(int i = j; i < k;i++) #define MAX(x,a) x=((x)<(a))?(a):(x); #define MIN(x,a) x=((x)>(a))?(a):(x); using namespace std; typedef int Type; const int N = 1000; const Type eps = 1e-8; struct point { Type x,y; int v; int ind; bool legal; point(){} point(Type _x,Type _y){ x=_x,y=_y;} friend bool operator < (const point &l, const point &r) { return l.y < r.y || (l.y == r.y && l.x < r.x); } void input(){ scanf("%d %d %d",&x,&y,&v); legal = false; } }P[N],res[N],K[N]; //叉积 // P1 // \ // .p0 \ // p2 // 这种情况。返回结果顺时针<0,逆时针>0 long long Multi(point p1, point p2, point p0) { return (long long)(p1.x - p0.x) * (p2.y - p0.y) - (long long)(p2.x - p0.x) * (p1.y - p0.y); } //逆时针顺序 //p数组是点集, res是最后的结果集 , 同一条线上的会被移除一些。但可以修改 <=来避免 int Graham(point p[], int n, point res[]) { int top = 1; sort(p, p + n); if (n == 0){ return 0; } res[0] = p[0]; if (n == 1) return 1; res[1] = p[1]; if (n == 2) return 2; res[2] = p[2]; for (int i = 2; i < n; i++) { while (top && (Multi(p[i], res[top], res[top - 1]) >= 0)) //这里更改是逆时针还是顺时针 top--; res[++top] = p[i]; } int len = top; res[++top] = p[n - 2]; for (int i = n - 3; i >= 0; i--) { //只有当你需要求凸包上有多少个时,你才需要去掉 = . while (top != len && (Multi(p[i], res[top], res[top - 1]) >= 0)) //这里更改是逆时针还是顺时针 top--; res[++top] = p[i]; } //需要注意的是 最后点为 0 1 2 3 0,top指向最后一个元素 ,top就是里面的元素的数目了。。 return top; } int maxv,fn; int top; bool vis[N]; char s[N]; // p1.x <= a.x && a.x <= p2.x && p1.y <= a.y && a.y <= p2.y // && bool inLine(point a,point p1,point p2){ if( (p1.x <= a.x && a.x <= p2.x) || (p2.x <= a.x && a.x <= p1.x)) if( (p1.y <= a.y && a.y <= p2.y) || p2.y <= a.y && a.y <= p1.y) if( Multi(p1,p2,a) == 0 ) return true; return false; } bool Equal(point i,point j){ if( i.x == j.x && i.y == j.y && i.v==j.v){ return true; } return false; } int main(){ int n; int tt = 0; while(scanf("%d",&n)!=EOF){ if(n == 0) break; memset(vis,0,sizeof(vis)); rep(i,0,n)P[i].input(),P[i].ind = i; fn = 0 , maxv = 0; rep(i,0,n){ if(P[i].v > maxv){ maxv = P[i].v; } } rep(i,0,n) if(P[i].v == maxv){ K[fn++] = P[i]; } top = Graham(K,fn,res); for(int i = 0;i < n;i++) s[i]='0'; s[n]='\0'; for(int i = 0; i < top;i++) { vis[res[i].ind] = true,s[res[i].ind] = '1'; } for(int j = 0;j < n;j++){ if(P[j].v == maxv) for(int i = 0;i < top;i++) if(inLine(P[j],res[i],res[i+1])){ s[j] = '1'; break; } } for(int i = 0;i < n;i++) if(P[i].v == maxv) for(int j = 0;j < n;j++) if(i!=j) if(Equal(P[i],P[j])){ s[P[i].ind] = '0'; break; } rep(i,0,n) if(P[i].v < maxv) s[i] = '0'; if(maxv == 0){ rep(i,0,n) s[i] = '0'; } printf("Case #%d: %s\n",++tt,s); } return 0; }