题目:
Description
一个房间里有n盏灯泡,一开始都是熄着的,有1到n个时刻,每个时刻i,我们会将i的倍数的灯泡改变状态(即原本开着的现将它熄灭,原本熄灭的现将它点亮),问最后有多少盏灯泡是亮着的。
Input
一个数n
Output
m,表示最后有m盏是亮着的
Sample Input
5
Sample Output
2
Data Constraint
Hint
范围:40%的数据保证,n<=maxlongint
100%的数据保证,n<=10^200
作者思路:高精度平方根。我们知道,一个n位数<=(ndiv2)(ndiv2)相乘,所以先把长度div 2,从9至0枚举,不要从0至9。
代码:
var a,b,c:array[0..251] of longint;
l:longint;
procedure init;
var i:longint;
st:string;
begin
readln(st);
l:=length(st);
for i:=1 to l do c[250-(l-i)]:=ord(st[i])-48;
end;
procedure main;
var i,j,k,w:longint;
begin
for i:=250-l div 2 to 250 do
for j:=9 downto 0 do
begin
a[i]:=j;
fillchar(b,sizeof(b),0);
for k:=150 to 250 do
for w:=150 to 250 do
b[k+w-250]:=b[k+w-250]+a[k]*a[w];
for k:=250 downto 1 do
begin
b[k-1]:=b[k-1]+b[k] div 10;
b[k]:=b[k] mod 10;
end;
for k:=0 to 250 do if b[k]<>c[k] then break;
if b[k]<=c[k] then break;
end;
end;
procedure print;
var i,j:longint;
begin
for i:=0 to 250 do if a[i]<>0 then break;
for j:=i to 250 do write(a[j]);
end;
begin
init;
main;
print;
end.