【数论】Cube
program liukeke; var a:array[0..150] of longint; b:array[0..150] of longint; c:array[0..250] of longint; d:array[0..350] of longint; i,j:longint; s:string; procedure change(s:string); var i:longint; begin for i:=length(s) downto 1 do begin inc(a[0]); a[a[0]]:=ord(s[i])-48; end; end; function work:boolean; var i,j:longint; begin fillchar(c,sizeof(c),0); fillchar(d,sizeof(d),0); c[0]:=b[0]+b[0]-1; for i:=1 to b[0] do for j:=1 to b[0] do inc(c[i+j-1],b[i]*b[j]); for i:=1 to c[0] do if c[i]>10 then begin inc(c[i+1],c[i] div 10); c[i]:=c[i] mod 10; end; while c[c[0]]>0 do begin inc(c[0]); inc(c[c[0]+1],c[c[0]] div 10); c[c[0]]:=c[c[0]] mod 10; end; d[0]:=c[0]+b[0]-1; for i:=1 to b[0] do for j:=1 to c[0] do inc(d[i+j-1],c[i]*b[j]); for i:=1 to d[0] do if d[i]>10 then begin inc(d[i+1],d[i] div 10); d[i]:=d[i] mod 10; end; while d[d[0]]>0 do begin inc(d[0]); inc(d[d[0]+1],d[d[0]] div 10); d[d[0]]:=d[d[0]] mod 10; end; if d[b[0]]=a[b[0]] then exit(true) else exit(false); end; begin assign(input,'cube.in');reset(input); assign(output,'cube.out');rewrite(output); readln(s); change(s); for i:=1 to a[0] do begin inc(b[0]); for j:=0 to 9 do begin b[b[0]]:=j; if work then break; end; end; while b[b[0]]=0 do dec(b[0]); for i:=b[0] downto 1 do write(b[i]); close(input); close(output); end.
【题目描述】
给定一个以1,3,7或9结尾的数M,一定可以找到一个数N,N的三次方是以M结尾的,而且N的位数不超过M的位数。求N。
【输入文件】
输入一行,一个整数M,M不超过100位。
【输出文件】
输出一行,一个整数N,不要输出前导0。保证数据有唯一解。
【样例】
Cube.in
123
Cube.out
947
【数据规模】
对于30%的数据,M不超过10位;
对于100%的数据,M不超过100位。
分析
这么多位数,一定要用高精度的。枚举的思想,我们可以发现如果要确定一个n位数三次方后得数的后n位是确定,无论在此数之前加上什么数字,只要这n位不变,三次方后的数的后n位不变。所以我们可以对每一位进行枚举。每位都有0~9,从1位数枚举到m位数,每次枚举一位,然后对没举出的数三次方,看当前位是否和答案的对应位相等(要对整体三次方,该位之后的已经确定)即可。
code
反思
用数学规律对枚举算法经行优化。