題意:
用1*1*1的小立方體疊成一個A*B*C立方體,然後給出N個小立方體的中心(x,y,z)然後依次拿走該立方體,在拿走N個立方體後求剩下立方結合體的表面積。
思路:
首先算出當前立方體的表面積記爲sum,然後判斷現在要拿走的立方體有多少個面記爲s1已經被算在裏面了,即可得出沒有算的面爲6-s1,就可以知道拿走這個立方體後,丟失了s1個面,然後得到了6-s1的面,;但你每次拿走該立方體時必須要考慮它與之前已經拿走的立方體是否相鄰,然後記錄相鄰的個數s,即當前表面積爲sum +6-2*s1;
代碼:
#include<cstdio>
#include <cmath>
using namespace std;
#define maxn 1111
typedef long long LL;
struct point
{
int x,y,z;
}points[maxn];
int main()
{
#ifdef CDZSC_June
freopen("t.txt", "r", stdin);
#endif
int n,s;
LL sum,s1,a,b,c;
while(~scanf("%lld%lld%lld%d",&a,&b,&c,&n))
{
sum = 2*a*b + 2*a*c + 2*c*b;//計算當前表面積
for(int i = 0; i<n; i++)
{
s = s1 = 0;
scanf("%d%d%d",&points[i].x,&points[i].y,&points[i].z);
if(points[i].x == a -1 || points[i].x == -1){//判斷前面的面是否被算在sum裏面了
s1++;
}
if(points[i].x == a || !points[i].x){//判斷後面的面是否被算在sum裏面了
s1++;
}
if(points[i].y == b -1 || points[i].y== -1){//判斷右面的面是否被算在sum裏面了
s1++;
}
if(points[i].y == b || !points[i].y){//判斷左面的面是否被算在sum裏面了
s1++;
}
if(points[i].z == c -1 || points[i].z == -1 ){//判斷上面的面是否被算在sum裏面了
s1++;
}
if(points[i].z == c || !points[i].z){//判斷下面的面是否被算在sum裏面了
s1++;
}
for(int j = 0; j<i; j++)
{//判斷當前立方體與之前已經拿走的立方體是否相鄰
if(i!=j && ((abs(points[j].x - points[i].x) == 1 && points[j].y == points[i].y && points[j].z == points[i].z)
|| (abs(points[j].y - points[i].y) == 1 && points[j].x == points[i].x && points[j].z == points[i].z)
|| (abs(points[j].z - points[i].z) == 1 && points[j].y == points[i].y && points[j].x == points[i].x))){
s++;
}
}
sum += (6-2*s1-2*s);
}
printf("%lld\n",sum);
}
return 0;
}