UVA Wall

这个题也很简单。  就是求凸包。  然后 求外围凸包的和就行。 问题就出在 没一个点的地方的处理。


因为是求最小的距离。那么在点的地方。 外围就是要求最小就是圆弧。  对于 所有的点的圆弧 加起来 正好是一个完整的圆(因为要围一圈)。


所以 最小距离 就是  凸包的距离  +   圆的周长。


#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <cctype>
using namespace std;
#define ll long long
typedef unsigned long long ull;
#define maxn 1001
#define INF 1<<30
struct Point{
    double x,y;
    Point(double x = 0, double y = 0):x(x),y(y) {}
};
typedef Point Vector ;
Vector operator + (Vector A, Vector B){ return Vector(A.x + B.x, A.y + B.y);}
Vector operator - (Vector A, Point B){return Vector(A.x - B.x, A.y - B.y);}
Vector operator * (Vector A, double p){return Vector(A.x * p, A.y * p);}
Vector operator / (Vector A, double p){return Vector(A.x / p, A.y / p);}
bool operator < (const Point & a, const Point & b){
    return a.x < b.x || (a.x == b.x && a.y < b.y);
}
const double eps = 1e-10;
int dcmp(double x){
    if(fabs(x) < eps) return 0;
    else return x < 0 ? -1 : 1;
}
bool operator == (const Point & a, const Point & b){
    return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}
double Dot(Vector A, Vector B){ return A.x * B.x + A.y * B.y;} // 点积
double Length(Vector A) { return sqrt(Dot(A, A));}             //向量长度
double Angle(Vector A, Vector B){ return acos(Dot(A, B)/Length(A)/Length(B));}
                                                                //夹角
double Cross(Vector A, Vector B){return A.x*B.y - A.y * B.x;}   //叉积(面积两倍)
double Area2(Point A, Point B, Point C){return Cross(B-A,C-A);} // 面积两倍
Vector Rotate(Vector A, double rad){return Vector(A.x*cos(rad) - A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad));}// 旋转后的直线</span>


Vector Normal(Vector A){
    double L = Length(A);
    return Vector(-A.y/L, A.x/L);
}
Point GetLineIntersection(Point P, Point v, Point Q, Point w){  //求直线 pv 与qw的交点
    Vector u = P-Q;
    double t = Cross(w, u) / Cross(v, w);
    return P+v*t;
}
double DistanceToline(Point P, Point A, Point B){                //点到直线的距离
    Vector v1 = B - A,v2 = P - A;
    return fabs(Cross(v1,v2))/Length(v1);
}
double DistanceTpsegment(Point P, Point A, Point B){             //点到线段的距离
    if(A == B) return Length(P-A);
    Vector v1 = B - A, v2 = P - A, v3 = P - B;
    if(dcmp(Dot(v1, v2)) < 0) return Length(v2);
    else if(dcmp(Dot(v1,v3)) > 0) return Length(v3);
    else return fabs(Cross(v1, v2)) / Length(v1);
}
Point GetLinePrijection(Point P, Point A, Point B){             // 点在直线上的投影
    Vector v = B-A;
    return A+v*(Dot(v, P-A)/Dot(v,v));
}
bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2){ // 线段相交判定(不包括在端点处的情况)
    double c1 = Cross(a2 - a1,b1-a1) ,c2 = Cross(a2 - a1,b2-a1),
    c3 = Cross(b2 - b1, a1-b1), c4 = Cross(b2 - b1, a2 - b1);
    return dcmp(c1)*dcmp(c2) < 0 && dcmp(c3)*dcmp(c4) < 0;
}
bool OnSegment(Point p, Point a1, Point a2){                              //线段在端点处是否可能相交
    return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0;
}
double ConvexPolygonArea(Point * p,int n){                         // 多边形的有向面积
    double area = 0;
    for(int i = 1; i < n-1; i++)
        area += Cross(p[i] - p[0],p[i+1] - p[0]);
    return area/2;
}
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 main (){
    int kase;
    int counts = 0;
    scanf("%d",&kase);
    while(kase--){
        if(counts)
        printf("\n");
        counts++;
        int n;
        double r;
        Point p[maxn];
        Point af[maxn];
        scanf("%d%lf",&n,&r);
        for(int i = 0; i < n; i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);
        int m = ConvexHull(p, n, af);
        double sum = 0;
        for(int i = 0; i < m; i++)
            sum += Length(af[i] - af[(i+1)%m]);
        double pi = acos(-1);
        sum += pi*r*2;
        printf("%.0lf\n",sum);
    }
    return 0;
}


There were different types of fish in your aquarium. But they did not go along well with each other. So there had been Fish-War-1 among them. It was a complete mess. Lot of fishes died, many of them hid in some mountain, some were eaten by other fishes and so on. So you decided to compartmentalize your aquarium. You divided your aquarium into R x C grids, that is R rows and C columns. Then you inserted walls into each cell. The walls are slanted, that is it goes from north-east corner to south-west corner or north-west corner to south-east corner. They look like “/” or “\” respectively. Many years passed since the war. Now the fishes want to unite again. They want to bring down the walls. They measured the strength of each of the walls. What is the minimum amount of strength they need to spend to unite all the compartments? For example, in the following 2 x 2 grid, they can spend 7 + 9 + 12 = 28 unit strength to unite the 4 compartments. And this is the minimum. First line of the input contains number of test case T (<= 20). Hence follows T test cases. First line of the test case describes number of row R and number of columns C (1 <= R, C <= 100). Next R lines describe the walls. Each of these lines contains C characters and the characters are either “/” or “\”. Next R lines contain C positive integers, each describes the strength of the wall at the corresponding cell. The strength of a wall would be at most 10,000. For each test case output the case number and the minimum amount of strength to unite all the compartments in the aquarium. 输入样例 2 2 2 \/ \\ 7 10 12 9 1 3 /\\ 3 4 5 输出样例 Case 1: 28 Case 2: 12
最新发布
12-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值