題目:求給定數字的平方根。
分析:數學,二分。可以利用模擬(手算開方)或者二分求解。
說明:需要把數位壓縮,否則會TLE。
#include <cstring>
#include <cstdio>
char buf[1111];
int tag[505], mul[505], tem[1111];
int lef[505], rig[505], mid[505];
void bs(int L)
{
for (int i = 0; i <= 500; ++ i)
lef[i] = rig[i] = 0;
int l = (L+1)>>1;
rig[l] = 1;
int ans = 0, small = 1, end = L;
while (small) {
for (int i = 0; i <= l; ++ i)
mid[i] = lef[i]+rig[i];
mid[0] ++;
for (int i = 0; i <= l; ++ i) {
mid[i+1] += mid[i]/1000;
mid[i] %= 1000;
}
for (int i = l; i >= 0; -- i) {
if (i && mid[i]%2)
mid[i-1] += 1000;
mid[i] >>= 1;
}
end = l;
while (end > 0 && !mid[end]) -- end;
for (int i = 0; i <= L; ++ i)
mul[i] = 0;
for (int i = 0; i <= end; ++ i)
for (int j = 0; j <= end; ++ j)
mul[i+j] += mid[i]*mid[j];
for (int i = 0; i <= L; ++ i) {
mul[i+1] += mul[i]/1000;
mul[i] %= 1000;
}
ans = 0;
for (int i = L; i >= 0; -- i)
if (mul[i] != tag[i]) {
ans = mul[i]-tag[i];
break;
}
if (ans > 0) {
for (int i = 0; i <= l; ++ i)
rig[i] = mid[i];
rig[0] --;
for (int i = 0; rig[i] < 0; ++ i) {
rig[i] += 1000;
rig[i+1] --;
}
}else {
for (int i = 0; i <= l; ++ i)
lef[i] = mid[i];
}
end = l;
while (end >= 0 && lef[end] == rig[end]) -- end;
small = (end >= 0 && lef[end] < rig[end]);
}
end = l;
while (end > 0 && !lef[end]) -- end;
printf("%d",lef[end --]);
while (end >= 0) printf("%03d",lef[end --]);
printf("\n");
}
int main()
{
int n;
scanf("%d",&n);
while (n --) {
memset(tag, 0, sizeof(tag));
memset(tem, 0, sizeof(tem));
scanf("%s",buf);
int L = strlen(buf);
for (int i = L-1; i >= 0; -- i)
tem[i] = buf[L-1-i]-'0';
int save = 0;
for (int i = 0; i < L; i += 3)
tag[save ++] = tem[i]+tem[i+1]*10+tem[i+2]*100;
bs(save);
if (n) printf("\n");
}
return 0;
}