
The initial challenge here is: What algorithm is appropriate? After a few minutes of thinking, no particular algorithm or trick presents itself. Thus, one reverts to 'Brute Force'.
Initially, one can well imagine a Brute Force solution that checks successive integers as candidate solutions by examining the decimal part of their square root. This works fairly well, but obviously takes a while when a test case requires a solution that's fairly large (and you know the test cases will do this just to spite your program).
Russ Cox's insight was that the square root of an integer has an integer and decimal part -- and candidate solutions can be drawn by checking the square of ever-increasing integers added to the supplied fractional part. If the integer close to the square does not have the proper square root, one moves on to the next candidate.
How to check the decimal part? Changing it to characters (or a string) is surely one of the slowest ways. I think it's easiest to subtract the integer part (easy to find!) of the square root to yield the decimal part. Multiply that decimal part by a properly scaled 10n to yield an integer which needs to match the input fraction (which is also expressed as an integer). Integer compares are simple, quick, and accurate.
Here is Rob's solution, which utilizes Russ Cox's insight:
#include <stdio.h>
#include <math.h>
main () {
int i, j, l, goal, n;
double x, y, frac, multiplier;
FILE *fin = fopen ("roots.in", "r");
FILE *fout = fopen ("roots.out", "w");
fscanf(fin, "%d", &l);
fscanf(fin, "%d", &goal);
for (multiplier = 1.0, i = 0; i < l; i++)
multiplier *= 10.0;
frac = goal/multiplier;
for(i=1; i<46000; i++){
n = (i+frac) * (i+frac) + 0.5;
j = x = sqrt ( (double) n);
x -= j;
j = multiplier * x;
if (j == goal) {
fprintf(fout, "%d\n", n);
exit (0);
}
}
fprintf(fout, "oops\n");
return 0;
}