【数论】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

 

反思

用数学规律对枚举算法经行优化。

posted @ 2011-07-20 17:07  liukee  阅读(364)  评论(0编辑  收藏  举报