HDU 4946 凸包 判重点 多校练习赛8 1002

来源:互联网 发布:mac网页图片显示问号 编辑:程序博客网 时间:2024/04/30 07:42


题目意思很无聊, 你可以证明两点。

A、 速度最大的才能到最远点

B、 只有凸包边上的点才能到无穷远点。


然后就是一个无聊的凸包, 人站在一起并且速度相同的要排除掉。

。。被自己这个模板坑死了。  。。后来手动加上判是否在凸包上才过掉。。白浪费了3小时。。

#include <cstdio>#include <cstdlib>#include <map>#include <set>#include <algorithm>#include <cstring>#include <iostream>#include <vector>#include <string>#include <queue>#include <sstream>#include <math.h>#define mp(x,y) make_pair(x,y)#define pii pair<int,int>#define pLL pair<long long ,long long>#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,逆时针>0long 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;}


0 0
原创粉丝点击