Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Cube Dividing

Pablo Cubarson is a well-known cubism artist. He is producing a new piece of work using a cuboid which consists of $A \times B \times C$ unit cubes. He plans to make a beautiful shape by removing $N$ units cubes from the cuboid. When he is about to begin the work, he has noticed that by the removal the cuboid may be divided into several parts disconnected to each other. It is against his aesthetics to divide a cuboid. So he wants to know how many parts are created in his plan.

Your task is to calculate the number of connected components in the cuboid after removing the $N$ cubes. Two cubes are connected if they share one face.

Input

The input consists of a single test case. The test case is formatted as follows:

$A$ $B$ $C$ $N$

$X_1$ $Y_1$ $Z_1$

...

$X_N$ $Y_N$ $Z_N$

The first line contains four integers $A$, $B$, $C$ and $N$. $A$, $B$ and $C$ ($1 \leq A,B,C \leq 10^6$) denote the size of the cuboid $-$ the cuboid has an $A$ unit width from left to right and a $B$ unit height from bottom to top, and a $C$ unit depth from front to back. $N$ ($0 \leq N \leq 20,000, N \leq A \times B \times C - 1$) denotes the number of the cubes removed in the Cubarson's plan. Each of the following $N$ lines contains three integers $X_i$ ($0 \leq X_i \leq A-1$), $Y_i$ ($0 \leq Y_i \leq B-1$) and $Z_i$ ($0 \leq Z_i \leq C - 1$). They denote that the cube located at the $X_i$-th position from the left, the $Y_i$-th from the bottom and the $Z_i$-th from the front will be removed in the plan. You may assume the given positions are distinct.

Output

Print the number of the connected components in the cuboid after removing the specified cubes.

Sample Input 1

2 2 2 4
0 0 0
1 1 0
1 0 1
0 1 1

Output for the Sample Input 1

4

Sample Input 2

3 3 3 1
1 1 1

Output for the Sample Input 2

1

Sample Input 3

1 1 3 2
0 0 0
0 0 2

Output for the Sample Input 3

1

Solution in C++14 (judge verdict: Wrong Answer)

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <cassert>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
// head

struct point {
	int x,y,z;
	point() {}
	point(int x,int y,int z):x(x),y(y),z(z){}
};
vector<point> vs;
int a,b,c,n,x,y,z;
map<point,int> pt;
set<point> del;
bool operator < (const point &a,const point &b) {
	return a.x<b.x||(a.x==b.x&&a.y<b.y)||(a.x==b.x&&a.y==b.y&&a.z<b.z);
}
bool valid(point p) {
	return p.x>=0&&p.x<a&&p.y>=0&&p.y<b&&p.z>=0&&p.z<c;
}
void dfs(point p) {
	vs.pb(p); pt[p]=1;
	rep(dx,-1,2) rep(dy,-1,2) rep(dz,-1,2) {
		point q(p.x+dx,p.y+dy,p.z+dz);
		if (pt.count(q)&&pt[q]==0) dfs(q);
	}
}
void dfs2(point p) {
	pt[p]=2;
	rep(dx,-1,2) rep(dy,-1,2) rep(dz,-1,2) if (abs(dx)+abs(dy)+abs(dz)==1) {
		point q(p.x+dx,p.y+dy,p.z+dz);
		if (pt.count(q)&&pt[q]==1) dfs2(q);
	}
}

int main() {
	scanf("%d%d%d%d",&a,&b,&c,&n);
	rep(i,0,n) {
		scanf("%d%d%d",&x,&y,&z);
		del.insert(point(x,y,z));
		rep(dx,-1,2) rep(dy,-1,2) rep(dz,-1,2) {
			point p(x+dx,y+dy,z+dz);
			if (valid(p)) pt[p]=0;
		}
	}
	for (auto p:del) pt.erase(p);
	vector<point> d;
	for (auto p:pt) d.pb(p.fi);
	int ret=1;
	for (auto p:d) if (pt[p]==0) {
		vs.clear();
		dfs(p);
		ret--;
		for (auto q:vs) if (pt[q]==1) {
			dfs2(p);
			ret++;
		}
	}
	printf("%d\n",ret);
}