#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct Vector
{
double x;
double y;
double z;
} Vector;
typedef struct Mesh
{
int a;
int b;
int c;
} Mesh;
typedef struct Figure
{
int numPoints;
Vector *points;
int numMeshes;
Mesh *meshes;
int **boundary;
} Figure;
Vector subtract(Vector v1, Vector v2)
{
Vector v = {v1.x - v2.x, v1.y - v2.y, v1.z - v2.z};
return v;
}
double dot(Vector v1, Vector v2)
{
double result = v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
return result;
}
Vector cross(Vector v1, Vector v2)
{
Vector v;
v.x = v1.y * v2.z - v1.z * v2.y;
v.y = v1.z * v2.x - v1.x * v2.z;
v.z = v1.x * v2.y - v1.y * v2.x;
return v;
}
void setBoundary(Figure *figure)
{
figure
->boundary
= malloc(sizeof(int *) * figure
->numPoints
); for (int i = 0; i < figure->numPoints; i++)
{
figure
->boundary
[i
] = calloc(figure
->numPoints
, sizeof(int)); }
for (int i = 0; i < figure->numMeshes; i++)
{
int a = figure->meshes[i].a;
int b = figure->meshes[i].b;
int c = figure->meshes[i].c;
figure->boundary[a][b]++;
figure->boundary[b][c]++;
figure->boundary[c][a]++;
}
}
Figure *makeFigure()
{
Figure
*figure
= malloc(sizeof(Figure
)); scanf("%d", &figure
->numPoints
); figure
->points
= malloc(sizeof(Vector
) * figure
->numPoints
); for (int i = 0; i < figure->numPoints; i++)
{
scanf("(%lf, %lf, %lf)", &figure
->points
[i
].
x, &figure
->points
[i
].
y, &figure
->points
[i
].
z); }
scanf("%d", &figure
->numMeshes
); figure
->meshes
= malloc(sizeof(Mesh
) * figure
->numMeshes
); for (int i = 0; i < figure->numMeshes; i++)
{
scanf("(%d, %d, %d)", &figure
->meshes
[i
].
a, &figure
->meshes
[i
].
b, &figure
->meshes
[i
].
c); }
setBoundary(figure);
return figure;
}
void freeFigure(Figure *figure)
{
for (int i = 0; i < figure->numPoints; i++)
{
free(figure
->boundary
[i
]); }
}
int isOriented(Figure *figure)
{
for (int i = 0; i < figure->numPoints; i++)
{
for (int j = 0; j < figure->numPoints; j++)
{
if (figure->boundary[i][j] >= 2)
{
return 0;
}
}
}
return 1;
}
int isClosed(Figure *figure)
{
if (!isOriented(figure))
{
return 0;
}
else
{
for (int i = 0; i < figure->numPoints; i++)
{
for (int j = 0; j < figure->numPoints; j++)
{
if (figure->boundary[i][j] && !figure->boundary[j][i])
{
return 0;
}
}
}
return 1;
}
}
double calculateArea(Figure *figure)
{
double area = 0.0;
for (int i = 0; i < figure->numMeshes; i++)
{
Vector v1 = subtract(figure->points[figure->meshes[i].b], figure->points[figure->meshes[i].a]);
Vector v2 = subtract(figure->points[figure->meshes[i].c], figure->points[figure->meshes[i].a]);
Vector v = cross(v1, v2);
area
+= sqrt(dot
(v
, v
)) / 2; }
return area;
}
double calculatePerimeter(Figure *figure)
{
double perimeter = 0.0;
for (int i = 0; i < figure->numPoints; i++)
{
for (int j = 0; j < figure->numPoints; j++)
{
if (figure->boundary[i][j] == 1 && figure->boundary[j][i] != 1)
{
Vector v = subtract(figure->points[i], figure->points[j]);
perimeter
+= sqrt(dot
(v
, v
)); }
}
}
return perimeter;
}
double calculateVolume(Figure *figure)
{
double volume = 0.0;
for (int i = 0; i < figure->numMeshes; i++)
{
Vector v1 = figure->points[figure->meshes[i].a];
Vector v2 = figure->points[figure->meshes[i].b];
Vector v3 = figure->points[figure->meshes[i].c];
volume += dot(v1, cross(v2, v3)) / 6;
}
if (volume < 0)
{
volume = -volume;
}
return volume;
}
void printDetails(Figure *figure)
{
if (isOriented(figure))
{
if (isClosed(figure))
{
printf("closed and oriented\n"); printf("volume : %lf\n", calculateVolume
(figure
)); printf("area : %lf\n", calculateArea
(figure
)); return;
}
else
{
}
}
else
{
}
printf("area : %lf\n", calculateArea
(figure
)); printf("perimeter: %lf\n", calculatePerimeter
(figure
)); }
int main()
{
Figure *figure = makeFigure();
printDetails(figure);
freeFigure(figure);
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPG1hdGguaD4KCnR5cGVkZWYgc3RydWN0IFZlY3Rvcgp7CiAgICBkb3VibGUgeDsKICAgIGRvdWJsZSB5OwogICAgZG91YmxlIHo7Cn0gVmVjdG9yOwoKdHlwZWRlZiBzdHJ1Y3QgTWVzaAp7CiAgICBpbnQgYTsKICAgIGludCBiOwogICAgaW50IGM7Cn0gTWVzaDsKCnR5cGVkZWYgc3RydWN0IEZpZ3VyZQp7CiAgICBpbnQgbnVtUG9pbnRzOwogICAgVmVjdG9yICpwb2ludHM7CiAgICBpbnQgbnVtTWVzaGVzOwogICAgTWVzaCAqbWVzaGVzOwogICAgaW50ICoqYm91bmRhcnk7Cn0gRmlndXJlOwoKVmVjdG9yIHN1YnRyYWN0KFZlY3RvciB2MSwgVmVjdG9yIHYyKQp7CiAgICBWZWN0b3IgdiA9IHt2MS54IC0gdjIueCwgdjEueSAtIHYyLnksIHYxLnogLSB2Mi56fTsKICAgIHJldHVybiB2Owp9Cgpkb3VibGUgZG90KFZlY3RvciB2MSwgVmVjdG9yIHYyKQp7CiAgICBkb3VibGUgcmVzdWx0ID0gdjEueCAqIHYyLnggKyB2MS55ICogdjIueSArIHYxLnogKiB2Mi56OwogICAgcmV0dXJuIHJlc3VsdDsKfQoKVmVjdG9yIGNyb3NzKFZlY3RvciB2MSwgVmVjdG9yIHYyKQp7CiAgICBWZWN0b3IgdjsKICAgIHYueCA9IHYxLnkgKiB2Mi56IC0gdjEueiAqIHYyLnk7CiAgICB2LnkgPSB2MS56ICogdjIueCAtIHYxLnggKiB2Mi56OwogICAgdi56ID0gdjEueCAqIHYyLnkgLSB2MS55ICogdjIueDsKICAgIHJldHVybiB2Owp9Cgp2b2lkIHNldEJvdW5kYXJ5KEZpZ3VyZSAqZmlndXJlKQp7CiAgICBmaWd1cmUtPmJvdW5kYXJ5ID0gbWFsbG9jKHNpemVvZihpbnQgKikgKiBmaWd1cmUtPm51bVBvaW50cyk7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZ3VyZS0+bnVtUG9pbnRzOyBpKyspCiAgICB7CiAgICAgICAgZmlndXJlLT5ib3VuZGFyeVtpXSA9IGNhbGxvYyhmaWd1cmUtPm51bVBvaW50cywgc2l6ZW9mKGludCkpOwogICAgfQogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWd1cmUtPm51bU1lc2hlczsgaSsrKQogICAgewogICAgICAgIGludCBhID0gZmlndXJlLT5tZXNoZXNbaV0uYTsKICAgICAgICBpbnQgYiA9IGZpZ3VyZS0+bWVzaGVzW2ldLmI7CiAgICAgICAgaW50IGMgPSBmaWd1cmUtPm1lc2hlc1tpXS5jOwogICAgICAgIGZpZ3VyZS0+Ym91bmRhcnlbYV1bYl0rKzsKICAgICAgICBmaWd1cmUtPmJvdW5kYXJ5W2JdW2NdKys7CiAgICAgICAgZmlndXJlLT5ib3VuZGFyeVtjXVthXSsrOwogICAgfQp9CgpGaWd1cmUgKm1ha2VGaWd1cmUoKQp7CiAgICBGaWd1cmUgKmZpZ3VyZSA9IG1hbGxvYyhzaXplb2YoRmlndXJlKSk7CiAgICBzY2FuZigiJWQiLCAmZmlndXJlLT5udW1Qb2ludHMpOwogICAgZ2V0Y2hhcigpOwogICAgZmlndXJlLT5wb2ludHMgPSBtYWxsb2Moc2l6ZW9mKFZlY3RvcikgKiBmaWd1cmUtPm51bVBvaW50cyk7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZ3VyZS0+bnVtUG9pbnRzOyBpKyspCiAgICB7CiAgICAgICAgc2NhbmYoIiglbGYsICVsZiwgJWxmKSIsICZmaWd1cmUtPnBvaW50c1tpXS54LCAmZmlndXJlLT5wb2ludHNbaV0ueSwgJmZpZ3VyZS0+cG9pbnRzW2ldLnopOwogICAgICAgIGdldGNoYXIoKTsKICAgIH0KICAgIHNjYW5mKCIlZCIsICZmaWd1cmUtPm51bU1lc2hlcyk7CiAgICBnZXRjaGFyKCk7CiAgICBmaWd1cmUtPm1lc2hlcyA9IG1hbGxvYyhzaXplb2YoTWVzaCkgKiBmaWd1cmUtPm51bU1lc2hlcyk7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZ3VyZS0+bnVtTWVzaGVzOyBpKyspCiAgICB7CiAgICAgICAgc2NhbmYoIiglZCwgJWQsICVkKSIsICZmaWd1cmUtPm1lc2hlc1tpXS5hLCAmZmlndXJlLT5tZXNoZXNbaV0uYiwgJmZpZ3VyZS0+bWVzaGVzW2ldLmMpOwogICAgICAgIGdldGNoYXIoKTsKICAgIH0KICAgIHNldEJvdW5kYXJ5KGZpZ3VyZSk7CiAgICByZXR1cm4gZmlndXJlOwp9Cgp2b2lkIGZyZWVGaWd1cmUoRmlndXJlICpmaWd1cmUpCnsKICAgIGZyZWUoZmlndXJlLT5wb2ludHMpOwogICAgZnJlZShmaWd1cmUtPm1lc2hlcyk7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZ3VyZS0+bnVtUG9pbnRzOyBpKyspCiAgICB7CiAgICAgICAgZnJlZShmaWd1cmUtPmJvdW5kYXJ5W2ldKTsKICAgIH0KICAgIGZyZWUoZmlndXJlLT5ib3VuZGFyeSk7CiAgICBmcmVlKGZpZ3VyZSk7Cn0KCmludCBpc09yaWVudGVkKEZpZ3VyZSAqZmlndXJlKQp7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZ3VyZS0+bnVtUG9pbnRzOyBpKyspCiAgICB7CiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBmaWd1cmUtPm51bVBvaW50czsgaisrKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGZpZ3VyZS0+Ym91bmRhcnlbaV1bal0gPj0gMikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gMTsKfQoKaW50IGlzQ2xvc2VkKEZpZ3VyZSAqZmlndXJlKQp7CiAgICBpZiAoIWlzT3JpZW50ZWQoZmlndXJlKSkKICAgIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZ3VyZS0+bnVtUG9pbnRzOyBpKyspCiAgICAgICAgewogICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGZpZ3VyZS0+bnVtUG9pbnRzOyBqKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChmaWd1cmUtPmJvdW5kYXJ5W2ldW2pdICYmICFmaWd1cmUtPmJvdW5kYXJ5W2pdW2ldKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAxOwogICAgfQp9Cgpkb3VibGUgY2FsY3VsYXRlQXJlYShGaWd1cmUgKmZpZ3VyZSkKewogICAgZG91YmxlIGFyZWEgPSAwLjA7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZ3VyZS0+bnVtTWVzaGVzOyBpKyspCiAgICB7CiAgICAgICAgVmVjdG9yIHYxID0gc3VidHJhY3QoZmlndXJlLT5wb2ludHNbZmlndXJlLT5tZXNoZXNbaV0uYl0sIGZpZ3VyZS0+cG9pbnRzW2ZpZ3VyZS0+bWVzaGVzW2ldLmFdKTsKICAgICAgICBWZWN0b3IgdjIgPSBzdWJ0cmFjdChmaWd1cmUtPnBvaW50c1tmaWd1cmUtPm1lc2hlc1tpXS5jXSwgZmlndXJlLT5wb2ludHNbZmlndXJlLT5tZXNoZXNbaV0uYV0pOwogICAgICAgIFZlY3RvciB2ID0gY3Jvc3ModjEsIHYyKTsKICAgICAgICBhcmVhICs9IHNxcnQoZG90KHYsIHYpKSAvIDI7CiAgICB9CiAgICByZXR1cm4gYXJlYTsKfQoKZG91YmxlIGNhbGN1bGF0ZVBlcmltZXRlcihGaWd1cmUgKmZpZ3VyZSkKewogICAgZG91YmxlIHBlcmltZXRlciA9IDAuMDsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlndXJlLT5udW1Qb2ludHM7IGkrKykKICAgIHsKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGZpZ3VyZS0+bnVtUG9pbnRzOyBqKyspCiAgICAgICAgewogICAgICAgICAgICBpZiAoZmlndXJlLT5ib3VuZGFyeVtpXVtqXSA9PSAxICYmIGZpZ3VyZS0+Ym91bmRhcnlbal1baV0gIT0gMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVmVjdG9yIHYgPSBzdWJ0cmFjdChmaWd1cmUtPnBvaW50c1tpXSwgZmlndXJlLT5wb2ludHNbal0pOwogICAgICAgICAgICAgICAgcGVyaW1ldGVyICs9IHNxcnQoZG90KHYsIHYpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBwZXJpbWV0ZXI7Cn0KCmRvdWJsZSBjYWxjdWxhdGVWb2x1bWUoRmlndXJlICpmaWd1cmUpCnsKICAgIGRvdWJsZSB2b2x1bWUgPSAwLjA7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZ3VyZS0+bnVtTWVzaGVzOyBpKyspCiAgICB7CiAgICAgICAgVmVjdG9yIHYxID0gZmlndXJlLT5wb2ludHNbZmlndXJlLT5tZXNoZXNbaV0uYV07CiAgICAgICAgVmVjdG9yIHYyID0gZmlndXJlLT5wb2ludHNbZmlndXJlLT5tZXNoZXNbaV0uYl07CiAgICAgICAgVmVjdG9yIHYzID0gZmlndXJlLT5wb2ludHNbZmlndXJlLT5tZXNoZXNbaV0uY107CiAgICAgICAgdm9sdW1lICs9IGRvdCh2MSwgY3Jvc3ModjIsIHYzKSkgLyA2OwogICAgfQogICAgaWYgKHZvbHVtZSA8IDApCiAgICB7CiAgICAgICAgdm9sdW1lID0gLXZvbHVtZTsKICAgIH0KICAgIHJldHVybiB2b2x1bWU7Cn0KCnZvaWQgcHJpbnREZXRhaWxzKEZpZ3VyZSAqZmlndXJlKQp7CiAgICBpZiAoaXNPcmllbnRlZChmaWd1cmUpKQogICAgewogICAgICAgIGlmIChpc0Nsb3NlZChmaWd1cmUpKQogICAgICAgIHsKICAgICAgICAgICAgcHJpbnRmKCJjbG9zZWQgYW5kIG9yaWVudGVkXG4iKTsKICAgICAgICAgICAgcHJpbnRmKCJ2b2x1bWUgOiAlbGZcbiIsIGNhbGN1bGF0ZVZvbHVtZShmaWd1cmUpKTsKICAgICAgICAgICAgcHJpbnRmKCJhcmVhICAgOiAlbGZcbiIsIGNhbGN1bGF0ZUFyZWEoZmlndXJlKSk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcHJpbnRmKCJvcmllbnRlZFxuIik7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHByaW50ZigidW5vcmllbnRlZFxuIik7CiAgICB9CiAgICBwcmludGYoImFyZWEgICAgIDogJWxmXG4iLCBjYWxjdWxhdGVBcmVhKGZpZ3VyZSkpOwogICAgcHJpbnRmKCJwZXJpbWV0ZXI6ICVsZlxuIiwgY2FsY3VsYXRlUGVyaW1ldGVyKGZpZ3VyZSkpOwp9CgppbnQgbWFpbigpCnsKICAgIEZpZ3VyZSAqZmlndXJlID0gbWFrZUZpZ3VyZSgpOwogICAgcHJpbnREZXRhaWxzKGZpZ3VyZSk7CiAgICBmcmVlRmlndXJlKGZpZ3VyZSk7CiAgICByZXR1cm4gMDsKfQ==
NAooMC4wLCAwLjAsIDAuMCkKKDEuMCwgMC4wLCAwLjApCigwLjAsIDEuMCwgMC4wKQooMC4wLCAwLjAsIDEuMCkKNAooMCwgMiwgMSkKKDAsIDEsIDMpCigwLCAzLCAyKQooMSwgMiwgMyk=
4
(0.0, 0.0, 0.0)
(1.0, 0.0, 0.0)
(0.0, 1.0, 0.0)
(0.0, 0.0, 1.0)
4
(0, 2, 1)
(0, 1, 3)
(0, 3, 2)
(1, 2, 3)