遥控车(NDK1158)

算法:模拟+递推
 
分析:本题第一问的算法比较好想到,但是拿不了全分,其实第一问可以用Qsort+二分查找的方法,这样的话在复杂度为log的情况下能成功解决。
      本题第二问在有能力的情况下也是比较好推的,首先分析长度为1的排列方式只有1种,长度为2的排列方式只有2种。长度为N(N>2)的情况下,第N位可以与第N-1位不互换,即F[N-1],如果互换,那么只有前N-2位保持原样,即F[N-2],所以F[N]=F[N-1]+F[N-2]。最后使用一下高精度即可。
 
思考:数学性很强的递推可以先用搜索算出前几项然后再找规律。
program NDK1158;



const

 maxn=10000;

 

type

 arr=array [0..1000] of longint;



var

 n,m,ans:longint;

 name:array [0..maxn] of ansistring;

 f:array [0..maxn] of arr;



procedure init;

var

 i:longint;

begin

 ans:=0;

 readln(n,m);

 for i:=1 to n do readln(name[i]);

end;



procedure qsort(l,r:longint);

var

 i,j:longint;

 m,t:ansistring;

begin

 i:=l;

 j:=r;

 m:=name[(l+r) shr 1];

 repeat

  while name[i]<m do inc(i);

  while name[j]>m do dec(j);

  if i<=j then

   begin

    t:=name[i];

    name[i]:=name[j];

    name[j]:=t;

    inc(i);

    dec(j);

   end;

 until i>j;

 if i<r then qsort(i,r);

 if l<j then qsort(l,j);

end;



function max(x,y:longint):longint;

begin

 if x>y then exit(x) else exit(y);

end;



procedure main;

var

 i,l,r,mid:longint;

 s:ansistring;

begin

 for i:=1 to m do

  begin

   readln(s);

   l:=1;

   r:=n;

   while l<r do

    begin

     mid:=(l+r) shr 1;

     if s<=name[mid] then r:=mid else l:=mid+1;

    end;

   if pos(s,name[l])=1 then inc(ans);

  end;

end;



function GJJ(J1,J2:arr):arr;

var

 i,len,x:longint;

begin

 fillchar(GJJ,sizeof(GJJ),0);

 x:=0;

 len:=max(J1[0],J2[0]);

 for i:=1 to len do

  begin

   GJJ[i]:=J1[i]+J2[i]+x;

   x:=GJJ[i] div 10000;

   GJJ[i]:=GJJ[i] mod 10000;

  end;

 if x>0 then

  begin

   inc(len);

   GJJ[len]:=x;

  end;

 GJJ[0]:=len;

end;



procedure calc;

var

 i:longint;

begin

 f[1,0]:=1;

 f[1,1]:=1;

 f[2,0]:=1;

 f[2,1]:=2;

 for i:=3 to n do f[i]:=GJJ(f[i-1],f[i-2]);

end;



procedure print;

var

 i:longint;

begin

 for i:=f[n,0] downto 1 do

  begin

   if i=f[n,0] then write(f[n,i])

   else

    begin

     if f[n,i]<1000 then write(0);

     if f[n,i]<100 then write(0);

     if f[n,i]<10 then write(0);

     write(f[n,i]);

    end;

  end;

end;



begin

 assign(input,'NDK1158.in'); reset(input);

 assign(output,'NDK1158.out'); rewrite(output);



 init;

 qsort(1,n);

 main;

 calc;

 writeln(ans);

 print;

 

 close(input); close(output);

end.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值