Casco 3D convexo HDU-3662 Casco 3D convexo

Existem N pontos no espaço 3D que compõem um casco 3D convexo *. Quantas faces possui o casco 3D convexo? É garantido que todos os pontos não estão no mesmo plano. 

Caso você não saiba a definição de casco convexo, apresentamos aqui um esclarecimento da Wikipedia: 
* Casco convexo: Em matemática, o casco convexo, para um conjunto de pontos X em um espaço vetorial real V, é o mínimo convexo conjunto contendo X. 

InputThere são vários casos de teste. Em cada caso, a primeira linha contém um número inteiro N indica o número de pontos 3D (3 <N <= 300) e, em seguida, N linhas seguem, cada linha contém três números x, y, z (entre -10000 e 10000) indicam a posição 3d de um ponto. SaídaUtilize o número de faces do casco 3D-convexo. 
Entrada de amostra

7 
1 1 0 
1 -1 0 
-1 1 0 
-1 -1 0 
0 0 1 
0 0 0 
0 0 -0.1 
7 
1 1 0 
1 -1 0 
-1 1 0 
-1 -1 0 
0 0 1 
0 0 0 
0 0 0,1

Saída de amostra

8 
5

#include <cmath> 
#include <cstdio> 
#include <cstring> 
#include <algorithm>
 usando o  namespace std; 

const  int N = 303 ;
const  duplo eps = 1-6 ; 

ponto de estrutura {
     double x, y, z; 
    Ponto ( double _x = 0 , double _y = 0 , double _z = 0 ): x (_x), y (_y), z (_z) {} Operador de 
    ponto + ( const Point & A) const{
         Ponto de retorno (x + Ax, y + Ay, z + Az); 
    } Operador de 
    ponto - ( const Point & A) const {
         retornar ponto (x - Ax, y - Ay, z - Az); 
    } 
    operador duplo  * ( const Point & A) const {
         retorno x * Ax + y * Ay + z * Az; 
    } Operador de 
    ponto ^ ( const Point & A) const {
         retornar ponto (y * Az - z * Ay, z * Ax - x * Az, x * Ay - y * Ax);
    }
    sqrlen duplo () {
         retorno x * x + y * y + z * z; 
    } 
} P [N]; 

struct Face {
     int a, b, c; bool ex; 
    Face ( int _a = 0 , int _b = 0 , int _c = 0 , bool _ex = false ): a (_a), b (_b), c (_c), ex (_ex) {} 
} F [N * N ]; 

int n, ftot, LeftFace [N] [N]; 

void insFace ( int a, int b, int c, int n1, int n2, int n3) { 
    F [ ++ ftot] = (Face) {a, b, c, verdadeiro }; 
    LeftFace [a] [b] = LeftFace [b] [c] = LeftFace [c] [a] = ftot; 
    Lado esquerdo [b] [a] = n1; 
    Face esquerda [c] [b] = n2; 
    Face esquerda [a] [c] = n3; 
} 

bool visível ( int f, int p) { 
    Ponto a = P [F [f] .b] - P [F [f] .a], b = P [F [f] .c] - P [F [ f] .a];
    retorno (P [p] - P [F [f] .a]) * (a ^ b)> eps; 
} 

intst, para [N], ps [N], pt [N], ptot =0 , pf [N]; 

void dfs ( int x, int s, int t, int p) {
     if (F [x] .ex == false ) return ; 
    
    if (visível (x, p)) 
        F [x] .ex = false ;
    senão { 
        to [st = s] = t;
        retorno ; 
    } 
    
    dfs (Face esquerda [F [x] .b] [F [x] .a], F [x] .a, F [x] .b, p); 
    dfs (Lado Esquerdo [F [x]. c] [F [x]. b], F [x]. b, F [x]. c, p); 
    dfs (Face esquerda [F [x] .a] [F [x] .c], F [x] .c, F [x] .a, p); 
} 

Ponto ff; 
vaziodfs2 ( int x) {
     if (F [x] .ex == false ) return ; 
    
    Aponte agora = (P [F [x] .b] - P [F [x] .a]) ^ (P [F [x] .c] - P [F [x] .a]);
    if (fabs (agora * ff - sqrt (now.sqrlen () * ff.sqrlen ())) < 1-6 ) 
        F [x] .ex = false ;
    mais 
        retornar ; 
    
    dfs2 (Lado esquerdo [F [x] .b] [F [x] .a]); 
    dfs2 (Lado Esquerdo [F [x] .c] [F [x] .b]); 
    dfs2 (Lado Esquerdo [F [x] .a] [F [x] .c]); 
} 

int main () {
     while (~ scanf ( " % d " , &n)) {
         ;para ( int i = 1 ; i <= n; ++ i) scanf ( " % lf% lf% lf " , & P [i] .x, & P [i] .y, & P [i] .z); 
        ftot = 0 ; 
        Ponto a, b, c, d, e; 
        a = P [ 2 ] - P [ 1 ];
        int tmp, id1, id2;
        para (tmp = 3 ; tmp <= n; ++ tmp) { 
            b = P [tmp] - P [ 1 ]; 
            d = a ^ b;
            se (d.sqrlen () <eps) continuar
            id1= tmp; quebrar ; 
        } 
        para (++ tmp; tmp <= n; ++ tmp) { 
            c = P [tmp] - P [ 1 ];
            se (fabs (d * c) <eps) continuar ; 
            id2 = tmp; quebrar ; 
        } 
        
        if (d * c < 0 ) swap (id1, id2); 
        insFace ( 1 , 2 , id2, 3 , 4 , 2 ); 
        insFace ( 1 , id2, id1, 1 , 4 , 3 ); 
        insFace ( 1 , id1, 2 , 2 , 4 , 1 ); 
        insFace ( 2 , id1, id2, 3 , 2 , 1 ); 
        
        para ( int i = 3 ; i <= n; ++ i) {
             se (i == id1 || i == id2) continue ;
            for ( int j = 1 ; j <= ftot; ++ j)
                 if (F [j] .ex && visible (j, i)) { 
                    dfs (j, 0, 0 , i); 
                    ptot = 0 ;
                    int tmps = st, tmpt = para [st], ppff = ftot;
                    faça {
                         ++ ptot; 
                        ps [ptot] = tmps; pt [ptot] = tmpt; 
                        pf [ptot] = ++ ppff; 
                        tmps = tmpt; tmpt = para [tmpt]; 
                    } while (tmps! = st); 
                    
                    for ( int k = 1 , pre, suc; k <= ptot; ++ k) {
                        pre = k - 1 ; suc = k + 1 ;
                        if (pre == 0 ) pre = ptot;
                        if (suc> ptot) suc = 1 ; 
                        pre = pf [pré]; suc = pf [suc]; 
                        insFace (pt [k], i, ps [k], suc, pre, LeftFace [pt [k]] [ps [k]]); 
                    } 
                    
                    quebrar ; 
                } 
        } 
        
        int ans = 0 ;
        for ( int i = 1 ; i <= ftot; ++ i)
             se (F [i] .ex) {
                 ++ ans; 
                ff = (P [F [i] .b] - P [F [i] .a]) ^ (P [F [i] .c] - P [F [i] .a]); 
                dfs2 (i); 
            } 
        printf ( " % d \ n " , ans); 
    } 
    
    retornar  0 ; 
}

 

Acho que você gosta

Origin www.cnblogs.com/xxxsans/p/12677197.html
Recomendado
Clasificación