/* Thu Mar 18 16:52:52 JST 2004 */ /* Thu Mar 18 18:21:12 JST 2004 */ #include int division[9]; unsigned int unitsbyorder[9]; /* x y */ int sequence[3][3] = { {0, 5, 6}, /* y = 0 */ {1, 4, 7}, /* y = 1 */ {2, 3, 8} /* y = 2 */ }; void generate_unitsbyorder() { unsigned int i; unitsbyorder[1] = 8; for (i = 2; i < 9; i++) { unitsbyorder[i] = 9 * unitsbyorder[i-1] + 8; } } void generate_division() { unsigned int i, x; division[0] = 0; for (i = 1, x = 3; i <= 8; i++, x *= 3) { division[i] = x - 1; } } unsigned int nearest(int order, double p) { int smaller = (unsigned int)(p * division[order]); if (2*p - ((double)(smaller ) / (double)division[order] + (double)(smaller+1) / (double)division[order]) < 1e-8) { return smaller; } if (p - (double)smaller / (double)division[order] < (double)(smaller+1) / (double)division[order] - p) { return smaller; } return smaller+1; } int position(int order, int p) { return p / ((division[order] + 1) / 3); } unsigned int left_units(int x, int y, int order) { if (order > 1) { return left_units(x%((division[order]+1)/3), y%((division[order]+1)/3), order-1) + ((8-sequence[x/((division[order]+1)/3)][y/((division[order]+1)/3)]) * (unitsbyorder[order-1] + 1)); } else { if (x > 2 || y > 2) { return order / 0; } return 8 - sequence[x][y]; } } double distance(double x1, double y1, double x2, double y2) { return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); } int main() { int order, i_case; double dx1, dx2, dy1, dy2; int x1, x2, y1, y2, whole; unsigned int left_units1, left_units2, between_units; generate_division(); generate_unitsbyorder(); for (i_case = 0; ; i_case++) { scanf("%d", &order); if (order == 0) { break; } scanf("%lf %lf %lf %lf", &dx1, &dy1, &dx2, &dy2); x1 = nearest(order, dx1); y1 = nearest(order, dy1); x2 = nearest(order, dx2); y2 = nearest(order, dy2); whole = division[order] + 1; /* ordering? */ left_units1 = left_units(x1, y1, order); left_units2 = left_units(x2, y2, order); if (left_units1 < left_units2) { between_units = left_units2 - left_units1; } else { between_units = left_units1 - left_units2; } if (i_case > 0) { printf("\n"); } printf("Case %d. Distance is %.4lf\n", i_case + 1, ((double)(between_units) / division[order]) + distance((double)x1 / division[order], (double)y1 / division[order], dx1, dy1) + distance((double)x2 / division[order], (double)y2 / division[order], dx2, dy2)); } return 0; }