Problem:
Problem B:
Jaggie Spheres
Let
J
(
n
) be a three-dimensional body that
is a union of unit cubes whose all vertices lie on integer coordinates,
contains all points that are closer than the distance of √
n
to the origin, and
is the smallest of all such bodies.
The figure below shows how
J
(1),
J
(2), and
J
(3) look.
Figure 1: Jaggie Spheres for
n
= 1, 2, 3
Your task is to calculate how many faces
J
(
n
) have. Here, we define two square belong to the same face
if they are parallel and share an edge, but don’t if they share just a vertex.
Input
The input consists of multiple data sets, each of which comes with a single line containing an integer
n
(1 ≤
n
≤ 1000000). The end of input is indicated by
n
= 0.
Output
For each data set, print the number of faces
J
(
n
) have.
Sample Input
1
2
3
4
0
Output for the Sample Input
6
30
30
6

Submitted solutions:

code_snippet: #include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <queue>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 2000 + 10;
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};

int n;
int len, o;
int flag;
int h[N][N];
int vis[N][N];

int valid(int x, int y)
{
	return x >= 0 && y >= 0 && vis[x][y] == flag;
}

void bfs(int sx, int sy)
{
	queue<pair<int, int> > que;
	que.push(make_pair(sx, sy));
	vis[sx][sy] = flag + 1;
	int nx, ny;
	int px, py;
	for( ; que.size(); ) {
		nx = que.front().first;
		ny = que.front().second;
		que.pop();
		for(int i = 0; i < 4; ++ i) {
			px = nx + dx[i];
			py = ny + dy[i];
			if (valid(px, py) && h[nx][ny] == h[px][py]) {
				vis[px][py] = flag + 1;
				que.push(make_pair(px, py));
			}
		}
	}
}

void solve()
{
	len = 0;
	for( ; len * len < n; ++ len);
	o = len;

	++ flag;
	for(int i = 0; i <= 2 * len + 2; ++ i)
		for(int j = 0; j <= 2 * len + 2; ++ j)
			h[i][j] = 0;
	for(int x = -len; x <= len; ++ x) {
		for(int y = -len; y <= len; ++ y) {
			h[x + o][y + o] = 0;
			if (x * x + y * y < n) {
				int tmp = sqrt(n - x * x - y * y);
				for( ; tmp * tmp + x * x + y * y < n; ++ tmp);
				for( ; tmp > 0 && (tmp - 1) * (tmp - 1) + x * x + y * y >= n; -- tmp);
				h[x + o][y + o] = tmp;
			}
			//cout << x << ' ' << y << ' ' << h[x + o][y + o] << endl;
			vis[x + o][y + o] = flag;
		}
	}
	for(int i = 0; i <= 2 * len; ++ i) {
		for(int j = 0; j <= 2 * len; ++ j) {
			if (vis[i][j] == flag || vis[i + 1][j] == flag || vis[i][j + 1] == flag || vis[i + 1][j + 1] == flag) {
				h[i][j] = max(max(h[i][j], h[i + 1][j + 1]), max(h[i][j + 1], h[i + 1][j]));
				if (h[i][j] <= 0) continue;
				//cout << i << ' ' << j << ' ' << h[i][j] << endl;
				vis[i][j] = flag + 1;
			}
		}
	}
	++ flag;
	int ret = 0;
	for(int i = 0; i <= 2 * len; ++ i) {
		for(int j = 0; j <= 2 * len; ++ j) {
			if (vis[i][j] == flag) {
				ret += 6;
				bfs(i, j);
			}
		}
	}
	++ flag;
	cout << ret << endl;
}

int main()
{
	flag = 0;
	for( ; cin >> n && n; ) {
		solve();
	}
	return 0;
}
accuracy: 1
time_ms: 2300
memory_kb: 32732
final_rank: 5

code_snippet: #include<cmath>
#include<queue>
#include<cstdio>
#include<algorithm>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

const int dx[]={1,0,-1,0},dy[]={0,-1,0,1};

int main(){
	static int isqrt[1000001]; // isqrt[a] := ceil(sqrt(a))
	rep(a,1001) isqrt[a*a]=a;
	for(int a=999999;a>0;a--) if(isqrt[a]==0) isqrt[a]=isqrt[a+1];

	for(int n;scanf("%d",&n),n;){
		int n2=(int)ceil(sqrt(n));

		// 上から見た面
		const int O=n2; // offset
		static int h[2000][2000];
		rep(x,n2) rep(y,n2) {
			int z2=n-(x*x+y*y);
			if(z2<=0) h[x+O][y+O]=-1;
			else      h[x+O][y+O]=isqrt[z2];
		}
		// 左上 1/4 だけ高さを決めれば、残りは対称性からわかる
		rep(x,n2) rep(y,n2) h[O-x-1][y+O]=h[O-x-1][O-y-1]=h[x+O][O-y-1]=h[x+O][y+O];

		// painting
		int cnt=0;
		static bool vis[2000][2000];
		for(int x=-n2;x<n2;x++) for(int y=-n2;y<n2;y++) vis[x+O][y+O]=false;
		for(int x=-n2;x<n2;x++) for(int y=-n2;y<n2;y++) {
			if(vis[x+O][y+O] || h[x+O][y+O]==-1) continue;
			vis[x+O][y+O]=true;

			static queue< pair<int,int> > Q;
			Q.push(make_pair(x,y));
			while(!Q.empty()){
				int xx=Q.front().first,yy=Q.front().second; Q.pop();
				rep(k,4){
					int xxx=xx+dx[k],yyy=yy+dy[k];
					if(-n2<=xxx && xxx<n2 && -n2<=yyy && yyy<n2
					&& !vis[xxx+O][yyy+O] && h[xxx+O][yyy+O]==h[x+O][y+O]){
						vis[xxx+O][yyy+O]=true;
						Q.push(make_pair(xxx,yyy));
					}
				}
			}

			cnt++;
		}

		printf("%d\n",6*cnt);
	}

	return 0;
}
accuracy: 1
time_ms: 990
memory_kb: 23000
final_rank: 4

code_snippet: #include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <climits>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int,int> pii;
const int INF = 1<<29;
const double PI = acos(-1);
const double EPS = 1e-8;

int dy[] = {-1,0,1,0};
int dx[] = {0,1,0,-1};
int height[1001][1001];
bool visited[1001][1001];

int main() {
  ll n;
  while(cin >> n, n) {
    memset(visited,0,sizeof(visited));
    int sqn = sqrt(n);
    for (int y=0; y<=sqn; ++y) {
      for (int x=0; x*x+y*y<n; ++x) {
        height[y][x] = ceil(sqrt(n-x*x-y*y));
      }
    }
    int ans = 0;
    for (int y=0; y<=sqn; ++y) {
      for (int x=0; x*x+y*y<n; ++x) {
        if (visited[y][x]) continue;
        if (height[y][x] == 0) continue;
        queue<pii> Q;
        Q.push(pii(y,x));
        int flag = 0;
        while(!Q.empty()) {
          pii p = Q.front(); Q.pop();
          int y = p.first;
          int x = p.second;
          if (visited[y][x]) continue;
          visited[y][x] = 1;
          if (y == 0) flag |= 1;
          if (x == 0) flag |= 2;
          REP(i, 4) {
            int yy = y+dy[i];
            int xx = x+dx[i];
            if (yy<0||yy>sqn||xx<0||xx>sqn) continue;
            if (height[yy][xx] != height[y][x]) continue;
            if (visited[yy][xx]) continue;
            Q.push(pii(yy,xx));
          }
        }
        if (flag == 0) ans += 24;
        else if (flag == 1 || flag == 2) ans += 12;
        else ans += 6;
      }
    }
 
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 1070
memory_kb: 5808
final_rank: 2

code_snippet: #include<iostream>
#include<map>
#include<cmath>
#include<algorithm>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)

const int N = 1001;


int compute(int x,int y,int n){
  double z = sqrt(n-(double)x*x-(double)y*y);
  if (isnan(z))return 0;
  if ( fabs(z-(n-(double)x*x-(double)y*y))<1e-10)return (int)z;
  else return (int)ceil(z);
}

int height[N][N];
int th[N+1][N+1];

void estimate(int n,int tn){
  rep(i,tn)rep(j,tn)height[i][j]=0;
  rep(y,tn+1){
    rep(x,tn+1)th[y][x]=compute(x,y,n);
  }
  rep(y,tn){
    rep(x,tn){
      int p=0;
      height[y][x]=max(max(th[y][x],th[y+1][x]),
		       max(th[y+1][x],th[y+1][x+1]));
    }
  }
}

int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};

void dfs(int n,int y,int x,int d,bool &xzero,bool &yzero){
  if (y==-1||x==-1||y==n||x==n||height[y][x] != d)return;
  height[y][x]=0;
  if(x==0)xzero=true;
  if(y==0)yzero=true;
  rep(i,4)dfs(n,y+dy[i],x+dx[i],d,xzero,yzero);
}

int solve(int n){
  int ret=0;
  rep(i,n){
    rep(j,n){
      if (height[i][j] != 0){
	bool xzero=false,yzero=false;
	int tmp=1;
	dfs(n,i,j,height[i][j],xzero,yzero);
	if (xzero&&yzero);
	else if (xzero||yzero)tmp*=2;
	else tmp*=4;
	ret+=tmp;
      }
    }
  }
  return ret*6;
}

main(){
  int n;
  while(cin>>n && n){
    int tn = (int)(ceil(sqrt(n)));
    estimate(n,tn);
    cout << solve(tn) << endl;
  }
  return false;
}
accuracy: 1
time_ms: 1080
memory_kb: 8792
final_rank: 3

code_snippet: #include<iostream>
#include<set>
#include<cmath>
#include<queue>
using namespace std;
typedef pair<int,int> pi;
#define MAX 1024
const double eps = 1.0e-14;
static const int di [] = {1,0,-1,0};
static const int dj [] = {0,1,0,-1};
inline int ceilSqrt(int n){
  if(n<0)return 0;
  return (int)ceil(sqrt((double)n)-eps);
}

inline bool inside(pi p, int rmax){
  return 0<=p.first&&0<=p.second&&p.second<rmax&&p.first<rmax;
}

int main()
{
  while(true){
    static int Height[MAX][MAX];
    static bool vis[MAX][MAX];
    for(int i = 0; i < MAX; ++ i){
      for(int j = 0; j < MAX; ++j ){
	vis[i][j]=false;
	Height[i][j]=0;
      }
    }
    long long int ans = 0;
    long long int N;
    int rmax;
    cin >> N;
    if( N == 0 )break;

    rmax = ceilSqrt(N);
    queue<pi> q;
    q.push(pi(0,0));
    vis[0][0]=true;
    while(!q.empty()){
      pi now = q.front();q.pop();
      //cout << " NOW : " << now.first << ' ' << now.second << endl;
      Height[now.first][now.second] = ceilSqrt( N - (now.first)*(now.first) - (now.second)*(now.second) );
      if( Height[now.first][now.second] == 0 ) continue;
      for(int i = 0; i < sizeof(di)/sizeof(*di); ++i){
	pi next( now.first + di[i], now.second + dj[i] );
	if( !vis[next.first][next.second] && inside( next, rmax ) ){
	  vis[ next.first ][ next.second ] = true;
	  q.push( next );
	}
      }
    }

    for(int i = 0; i < MAX; ++i){
      for(int j = 0; j < MAX; ++j){
	vis[i][j]=false;
      }
    }
    
    //cout << " -------------------------------- " << endl;
    for(int i = 0; i < rmax; ++i){
      for(int j = 0; j < rmax; ++j){
	//if( N<120 )cout << Height[i][j];
	if( !vis[i][j] && Height[i][j] > 0 ){
	  bool i0=false,j0=false;
	  vis[i][j]=true;
	  q.push( pi(i,j) );
	  while(!q.empty()){
	    pi now = q.front();q.pop();
	    i0 |= now.first == 0;
	    j0 |= now.second == 0;
	    for(int k = 0; k < sizeof(di)/sizeof(*di); ++k){
	      pi next(now.first+di[k], now.second+dj[k] );
	      if( !vis[next.first][next.second] && Height[i][j] == Height[next.first][next.second] &&
		  inside( next, rmax ) ){
		vis[next.first][next.second]=true;
		q.push(next);
	      }
	    }
	  }
	  ans += (i0&&j0) ? 1 : ( (i0||j0) ? 2 : 4);
	}
      }
      //if( N < 120 ) cout << endl;
    }
    cout <<6LL*ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 500
memory_kb: 6036
final_rank: 1