回 帖 发 新 帖 刷新版面

主题:2005 noip考题 1道

看程序写结果的
program m;
var n:longint;
function g(k:longint):longint;
begin
if k<=1 then g:=k
     else g:=(2002*g(k-1)+2003*(k-2)) mod 2005
end;
begin
read(n);
writeln(g(n));
end.
输入 2005
输出:?
这个怎么算 ?  我感觉用笔好象根本算不出来

回复列表 (共16个回复)

沙发

g(x) = (-1)^(n-1)(2^n - 1) mod 2005
用数学归纳法可以证明
剩下来的工作就是求2^2005 mod 2005了。求出来是32,因此答案31

板凳

汗  偶像...
能否问下具体证明过程
我们还没学归纳法

3 楼

g(x) = (-1)^(n-1)(2^n - 1) mod 2005   (1)
当x=0,1的时候显然正确。
现在由定义,g(x) = (2002g(x-1) + 2003g(x-2)) % 2005
=(-3g(x-1) - 2g(x-2)) % 2005
=(-3*(-1)^(x-2)(2^(x-1)-1) - 2*(-1)^(x-3)(2^(x-2)-1)) % 2005
=(-1)^(x-3)(3*2^(x-1) - 3 - 2*2^(x-2) + 2) % 2005
=(-1)^(x-1)(2^x - 1) % 2005
即当g(x-2),g(x-1)成立时g(x)也成立
因此推出(1)式正确

4 楼

思路是怎么来得?   以便我以后能会这个类型的

5 楼

我在机器上运行时为什么很久不出结果????

6 楼

请问 楼主您哪个省的?
   好像noip今天才举行的吧?这么快就提问了?

7 楼

机器运行肯定出不了结果。你认为你的计算机调用2^2005次函数要多少时间内完成?
用这个检查答案吧:
int g(int x)
{
  int d[10000];
  d[0] = 0;d[1] = 1;
  for(int i=2;i<=x;i++)
    d[i] = 2002*d[i-1] + 2003*d[i-2];
  return d[i];
}

8 楼

不好意思我用C的,要用pascal的话翻译一下再运行

9 楼

原来是:
var n:integer;
function g(k:integer):integer;
begin
if k<=1 then
   g:=k
else
   g:=(g(k-1)*2002+g(k-2)*2003) mod 2005;
end;
begin
readln(n);
write(g(n));
end.
输入2005
输出:?
运行不了!!!
  
var a,b,c,n:integer;
begin
   a:=0;
   b:=1;
   for n:=2 to 2005 do begin
      c:=(2002*a+2003*b) mod 2005;
      writeln('g(',n,')=',c);
      a:=b;
      b:=c;
   end;
end.
改成递推后的
执行结果1994

10 楼

你写错了。答案肯定31。
应该c:=(2003*a+2002*b) mod 2005;

我来回复

您尚未登录,请登录后再回复。点此登录或注册