Sicily 1629. Area of Polycubes

来源:互联网 发布:视频剪切软件绿色版 编辑:程序博客网 时间:2024/05/30 05:41

1629. Area of Polycubes

Constraints

Time Limit: 5 secs, Memory Limit: 32 MB

Description

polycube is a solid made by gluing together unit cubes (one unit on each edge) on one or more faces. The figure in the lower-left is not a polycube because some cubes are attached along an edge.

For this problem, the polycube will be formed from unit cubes centered at integer lattice points in 3-space. The polycube will be built up one cube at a time, starting with a cube centered at (0,0,0). At each step of the process (after the first cube), the next cube must have a face in common with a cube previously included and not be the same as a block previously included. For example, a 1-by-1-by-5 block (as shown above in the upper-left polycube) could be built up as:


(0,0,0) (0,0,1) (0,0,2) (0,0,3) (0,0,4)


and a 2-by-2-by-2 cube (upper-right figure) could be built as:


(0,0,0) (0,0,1) (0,1,1) (0,1, 0) (1,0,0) (1,0,1) (1,1,1) (1,1, 0)


Since the surface of the polycube is made up of unit squares, its area is an integer.


Write a program which takes as input a sequence of integer lattice points in 3-space and determines whether is correctly forms a polycube and, if so, what the surface area of the polycube is.

Input

The first line of input contains a single integer N , (1≤N≤1000) which is the number of data sets that follow. Each data set consists of multiple lines of input. The first line contains the number of points P , (1 = P = 100) in the problem instance. Each succeeding line contains the centers of the cubes, eight to a line (except possibly for the last line). Each center is given as 3 integers, separated by commas. The points are separated by a single space.

Output

For each data set, you should generate one line of output with the following values: The data set number as a decimal integer (start counting at one), a space and the surface area of the polycube if it is correctly formed, OR, if it is not correctly formed, the string ``NO" a space and the index (starting with 1) of the first cube which does not share a face with a previous cube. Note that the surface area includes the area of any included holes.

Sample Input

4 5 0,0,0 0,0,1 0,0,2 0,0,3 0,0,4 8 0,0,0 0,0,1 0,1,0 0,1,1 1,0,0 1,0,1 1,1,0 1,1,1 4 0,0,0 0,0,1 1,1,0 1,1,1 20 0,0,0 0,0,1 0,0,2 0,1,2 0,2,2 0,2,1 0,2,0 0,1,0 1,0,0 2,0,0 1,0,2 2,0,2 1,2,2 2,2,2 1,2,0 2,2,0 2,1,0 2,1,2 2,0,1 2,2,1

Sample Output

1 22 2 24 3 NO 3 

4 72

// Problem#: 1629// Submission#: 3593580// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/// All Copyright reserved by Informatic Lab of Sun Yat-sen University/* * Polycube Solution * * by Fred Pickel * October 2008 */#include <stdio.h>#include <stdlib.h>#include <math.h>#define MAX_PROBS   1000#define EPS .001#define ERR .001char inbuf[512];int nCubes;int points[110][3];int ReadDataSet(int index){    int baseIndex, nLeft;    if(fgets(&(inbuf[0]), 255, stdin) == NULL)    {        fprintf(stderr, "read of cube count failed on problem %d\n", index);        return -1;    }    inbuf[255] = 0;    nCubes = atoi(&(inbuf[0]));    if((nCubes <= 0) || (nCubes > 100))    {        fprintf(stderr, "cube count %d out of range (1-100) on problem %d\n",            nCubes, index);        return -2;    }    baseIndex = 0;    nLeft = nCubes;    while(nLeft >= 8)    {        if(fgets(&(inbuf[0]), 255, stdin) == NULL)        {            fprintf(stderr, "read of cubes starting %d failed on problem %d\n",                baseIndex, index);            return -3;        }        inbuf[255] = 0;        if(sscanf(&(inbuf[0]),            "%d,%d,%d %d,%d,%d %d,%d,%d %d,%d,%d %d,%d,%d %d,%d,%d %d,%d,%d %d,%d,%d",            &points[baseIndex+0][0], &points[baseIndex+0][1], &points[baseIndex+0][2],             &points[baseIndex+1][0], &points[baseIndex+1][1], &points[baseIndex+1][2],             &points[baseIndex+2][0], &points[baseIndex+2][1], &points[baseIndex+2][2],             &points[baseIndex+3][0], &points[baseIndex+3][1], &points[baseIndex+3][2],             &points[baseIndex+4][0], &points[baseIndex+4][1], &points[baseIndex+4][2],             &points[baseIndex+5][0], &points[baseIndex+5][1], &points[baseIndex+5][2],             &points[baseIndex+6][0], &points[baseIndex+6][1], &points[baseIndex+6][2],             &points[baseIndex+7][0], &points[baseIndex+7][1], &points[baseIndex+7][2]) != 24)        {            fprintf(stderr, "scan of cubes starting %d failed on problem %d\n",                baseIndex, index);            return -4;        }        baseIndex += 8;        nLeft -= 8;    }    // do any left    if(nLeft > 0)    {        if(fgets(&(inbuf[0]), 255, stdin) == NULL)        {            fprintf(stderr, "read of cubes starting %d failed on problem %d\n",                baseIndex, index);            return -3;        }        inbuf[255] = 0;        if(sscanf(&(inbuf[0]),            "%d,%d,%d %d,%d,%d %d,%d,%d %d,%d,%d %d,%d,%d %d,%d,%d %d,%d,%d %d,%d,%d",            &points[baseIndex+0][0], &points[baseIndex+0][1], &points[baseIndex+0][2],             &points[baseIndex+1][0], &points[baseIndex+1][1], &points[baseIndex+1][2],             &points[baseIndex+2][0], &points[baseIndex+2][1], &points[baseIndex+2][2],             &points[baseIndex+3][0], &points[baseIndex+3][1], &points[baseIndex+3][2],             &points[baseIndex+4][0], &points[baseIndex+4][1], &points[baseIndex+4][2],             &points[baseIndex+5][0], &points[baseIndex+5][1], &points[baseIndex+5][2],             &points[baseIndex+6][0], &points[baseIndex+6][1], &points[baseIndex+6][2],             &points[baseIndex+7][0], &points[baseIndex+7][1], &points[baseIndex+7][2]) != 3*nLeft)        {            fprintf(stderr, "scan of cubes starting %d failed on problem %d\n",                baseIndex, index);            return -4;        }    }    return 0;}int IsNbr(int pt1[3], int pt2[3]){    if((pt1[0] == pt2[0]) && (pt1[1] == pt2[1]))    {        if(pt1[2] == pt2[2])        {   // same            return -1;        }        if(pt1[2] == (pt2[2]+1))        {            return 1;        }        if(pt1[2] == (pt2[2]-1))        {            return 1;        }    }    if((pt1[0] == pt2[0]) && (pt1[2] == pt2[2]))    {        if(pt1[1] == (pt2[1]+1))        {            return 1;        }        if(pt1[1] == (pt2[1]-1))        {            return 1;        }    }    if((pt1[2] == pt2[2]) && (pt1[1] == pt2[1]))    {        if(pt1[0] == (pt2[0]+1))        {            return 1;        }        if(pt1[0] == (pt2[0]-1))        {            return 1;        }    }    return 0;}// find out how many previous cubes have a face in common with cube// centered at pt return -1 if same as previous else count of faces in commonint CountNbrs(int pt[3], int prevPoint){    int i, ret, cnt;    for(i = 0, cnt = 0; i <= prevPoint ; i++)    {        ret = IsNbr(pt, &(points[i][0]));        if(ret < 0)        {            return -1;        }        else        {            cnt += ret;        }    }    return cnt;}int CountArea(){    int area, i, cnt;    area = 6;   // first cube    for(i = 1; i < nCubes ; i++)    {        cnt = CountNbrs(&(points[i][0]), i-1);        if(cnt <= 0)        {            return -(i+1);        }        else        {            area += (6 - 2*cnt);        }    }    return area;}int main(){    int probCnt, curProb, ret;    if(fgets(&(inbuf[0]), 255, stdin) == NULL)    {        fprintf(stderr, "read failed on problem count\n");        return -1;    }    inbuf[255] = 0;    probCnt = atoi(&(inbuf[0]));    if((probCnt < 1) || (probCnt > MAX_PROBS))    {        fprintf(stderr, "Problem count %d not in range 1...%d\n", probCnt, MAX_PROBS);        return -2;    }    for(curProb = 1; curProb <= probCnt ; curProb++)    {        if((ret = ReadDataSet(curProb)) != 0)        {            fprintf(stderr, "ReadDataSet returned %d on problem %d\n", ret, curProb);            return -3;        }        ret = CountArea();        if(ret < 0)        {            printf("%d NO %d\n", curProb, -ret);        }        else        {            printf("%d %d\n", curProb, ret);        }    }    return 0;}                                 


0 0
原创粉丝点击