Pagini recente » Cod sursa (job #2948634) | Cod sursa (job #730725) | Cod sursa (job #12857) | Cod sursa (job #735898) | Cod sursa (job #3242085)
#include <stdio.h>
#include <stdlib.h>
/*
I use the following terms:
Neighbour on the curve: A point Q on the curve is said
to be a neighbour of point P on the curve if and only if
the segment PQ is on the curve. Notice that the Hilbert
curve is piecewise linear, so it is formed from a certain
number of segments.
Beginning of Hilbert curve: One of the 2 points on the
curve that has exactly one neighbour on the curve. Notice
that, regardless of the curve's order, there are exactly
2 points that can be considered the beginning of the curve.
The rest of the points on the curve have exactly 2 neighbours.
Axis of symmetry: The axis of symmetry of the Hilbert curve
of some order. From the curve drawings shown in the examples,
it is clear that a Hilbert curve has exactly one axis of
symmetry, regardless of the order of the curve. (Maybe
this can be proven rigourously using the defintion
of the Hilbert curve.)
Center of a coordinate system: point with coordinates (1,1)
in that system (just to make it easier we use (1,1) instead
of (0,0)).
Definition of fractal(order,x,y), using the above terms:
fractal(order, x, y) gives the number of segments
that should be traversed to arrive from (1,1) to
(x,y) following a curve of order "order", given a coordinate
system centred at any of the 2 "beginning" points, with the x-axis being
perpendicular to the axis of symmetry and the y-axis parallel to the axis of
symmetry. The positive direction of the axis is chosen such that all points on
the curve have positive coordinates.
*/
int fractal(int order, int x, int y) {
/* If order = 0, there are no segments on the curve.
In fact, the curve is just a point in this case.
If order = 0, then x and y must be 1 for the function call to make sense.
*/
if (order == 0) return 0;
int pow2 = (1 << (order - 1));
// Segments needed to traverse a quarter of the curve: 4^(order-1) - 1.
// Recurrence is a_(n+1) = 4*a_n + 3, which can be solved to give the above.
int quarter = (1 << (2 * (order - 1))) - 1;
// Match the 2nd and 3rd parameters using the correct coordinate systems:
if (x <= pow2 && y <= pow2) return fractal(order - 1, y, x);
if (x <= pow2 && y > pow2)
return quarter + 1 + fractal(order - 1, x, y - pow2);
if (x > pow2 && y > pow2)
return 2 * quarter + 2 + fractal(order - 1, x - pow2, y - pow2);
if (x > pow2 && y <= pow2)
return 3 * quarter + 3 + fractal(order - 1, pow2 + 1 - y, 2 * pow2 + 1 - x);
}
int main() {
FILE *fp_in, *fp_out;
int k, x, y;
fp_in = fopen("fractal.in", "r");
fp_out = fopen("fractal.out", "w");
fscanf(fp_in, "%d %d %d", &k, &x, &y);
fprintf(fp_out, "%d", fractal(k, x, y));
fclose(fp_in);
fclose(fp_out);
return 0;
}