回 帖 发 新 帖 刷新版面

主题:[讨论]PASCAL技巧,分享者必加!

请大家踊跃发言!



1.尽量不要用sqrt,在只需要比较大小时,用平方时代替,因为sqrt很慢的。
   比如:在找距离最小时用平方数比较
2. 在用mod时,先用if判一下是否需要mod,因为mod很慢。
3. 超快有错判质数!!
   知识:
   费马小定理
   如果如果a,p互质且p是质数,则  a的p-1次方(用麦森数)  mod  p=1 
   反过来如果  a的p-1次方  mod   p=1 ,则p可能是质数,p随机出
function check(a,n:longint):longint;
var
   t,p,tot:int64;
begin
   p:=n-1;
   t:=a;
   tot:=1;
   while p<>0 do begin
      if p mod 2=1 then tot:=tot*t mod n;
      t:=t*t mod n;
      p:=p div 2;
      end;
   check:=tot mod n;
end;

function prime(n:longint):boolean;
var
   a,k:longint;
begin
   if n=1 then exit(false);
   if n<=3 then exit(true);
   for k:=1 to 6 do begin
      a:=random(n-2)+2;
      if check(a,n)<>1 then exit(false);
      end;
   exit(true);
end;
4.二分法
  left:=0;right:=long+1;
  while left<right-1 do
    begin
      if check(w) then left:=w else right:=w;
      w:=(left+right)div 2;
    end;
5.不用procedure的深搜

题目:
问题 12: 饮食问题 [Rob Kolstad, 2006]

Bessie 正在减肥,所以她规定每天不能吃超过 C (10 <= C <= 35,000)卡路里的食物。
农民 John 在戏弄她,在她面前放了B (1 <= B <= 21) 捅食物。每桶内都有某个单位
卡路里(范围:1..35,000)的食物(不一定相同)。Bessie 没有自控能力,一旦她开始
吃一个桶中的食物,她就一定把这桶食物全部吃完。 

Bessie 对于组合数学不大在行。请确定一个最优组合,使得可以得到最多的卡路里,
并且总量不超过C。

例如,总量上限是40卡路里, 6 桶食物分别含有7, 13, 17, 19, 29, 和 31卡路里的
食物。Bessie可以吃7 + 31 = 38卡路里,但是可以获取得更多: 7 + 13 + 19 = 39
卡路里。没有更好的组合了。

问题名称: eatpuz

输入格式:

* 行 1: 两个用空格分开的整数: C 和 B

* 行 2: B 个用空格分开的整数,分别表示每桶中食物所含的卡路里。

输入样例 (文件名 eatpuz.in):

40 6
7 13 17 19 29 31


输出格式:

* 行 1: 一个整数,表示Bessie能获得的最大卡路里,使她不违反减肥的规则。

输出样例 (文件名 eatpuz.out):

39

程序:
var
   a:array[1..100] of longint;
   b,c,sum,best,i,j:longint;

begin
   assign(input,'eatpuz.in'); reset(input);
   assign(output,'eatpuz.out'); rewrite(output);
   readln(c,b);
   best:=0;
   for i:=1 to b do read(a[i]);
   for i:=0 to 1 shl b - 1 do begin
      sum:=0;
      for j:=1 to b do
         if (i and (1 shl (j-1)))>0 then sum:=sum+a[j];
      if (sum>best) and (sum<=c) then best:=sum;
      end;
   writeln(best);
   close(input); close(output);
end.

6.作搜索最优性剪枝时,可先用贪心把max或者min算出作为剪枝条件,可加大效率。









☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆ 
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆■■■■■■■■■☆☆☆☆☆ 
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆■■■■■■■■■■■■■■■☆☆☆☆ 
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆■■■■■■■■■■■■■■■■■■☆☆☆☆ 
☆☆☆☆☆☆☆☆☆☆☆■■■■☆■■■■■■■■■■■☆☆☆☆☆☆☆☆☆☆ 
☆☆☆☆☆☆☆☆■■■■■■■☆■■■☆☆■■■■■☆☆☆☆☆☆☆☆☆☆☆ 
☆☆☆■■■■■■■■■■■■☆☆☆☆☆☆■■■■☆☆☆☆☆☆☆☆☆☆☆☆ 
☆■■■■■■■■■■■■■■☆☆☆☆☆☆■■■■☆☆☆☆☆☆☆☆☆☆☆☆ 
☆■■■■■■■■■■■■☆☆☆☆☆☆☆■■■■■■■■■■■☆☆☆☆☆☆ 
☆■■■■■■■■■■■■☆☆☆☆☆☆■■■■■■■■■■■■■☆☆☆☆☆ 
☆☆■■■■■■■■■■☆☆☆☆☆■■■■■■☆☆☆■■■■■■☆☆☆☆☆ 
☆☆☆☆☆☆☆☆■■■■☆☆☆☆☆■■■■☆☆☆☆☆☆■■■■■☆☆☆☆☆ 
☆☆☆☆☆☆☆☆■■■■☆☆☆☆■■■■☆☆■■☆☆☆■■■■■☆☆☆☆☆ 
☆☆☆☆☆☆☆☆■■■■☆☆☆☆■■■■☆■■■■☆☆■■■■■☆☆☆☆☆ 
☆☆☆☆☆☆☆☆■■■■☆☆☆☆■■■■☆■■■■☆☆■■■■■☆☆☆☆☆ 
☆☆☆☆☆☆☆☆■■■■☆☆☆☆■■■■☆■■■■☆☆■■■■■☆☆☆☆☆ 
☆☆☆☆☆☆☆☆■■■■☆☆☆☆■■■■☆■■■■☆☆■■■■■☆☆☆☆☆ 
☆☆☆☆☆☆☆☆■■■■☆☆☆☆■■■■☆■■■■☆☆■■■■■☆☆☆☆☆ 
☆☆☆☆☆☆☆☆■■■■☆☆☆☆■■■■☆■■■■☆☆■■■■■☆☆☆☆☆ 
☆☆☆☆☆☆☆☆■■■■☆☆☆☆■■■■☆■■■■☆☆■■■■■☆☆☆☆☆ 
☆☆☆☆☆☆☆☆■■■■☆☆☆☆■■■■☆■■■■☆☆■■■■■☆☆☆☆☆ 
☆☆☆☆☆☆☆☆■■■■☆☆☆☆■■■☆☆■■■■☆☆■■■■■☆☆☆☆☆ 
☆☆■■☆☆☆■■■■■☆☆☆☆■■■☆☆■■■☆☆☆■■■■■☆☆☆☆☆ 
☆☆■■■■■■■■■■☆☆☆☆☆■■☆☆■■☆☆☆☆■■■■■☆☆☆☆☆ 
☆☆☆■■■■■■■■■☆☆☆☆☆☆☆☆■■■☆☆☆☆☆■■■■☆☆☆☆☆ 
☆☆☆☆☆■■■■■■■☆☆☆☆☆☆☆☆■■■☆■■■■☆☆☆☆☆☆☆☆☆ 
☆☆☆☆☆☆■■■■■■☆☆☆☆☆☆☆■■■■☆☆■■■■■☆☆☆☆☆☆☆ 
☆☆☆☆☆☆☆☆☆■■■☆☆☆☆☆☆■■■■■☆☆☆■■■■■■☆☆☆☆☆ 
☆█████████☆☆☆☆☆☆☆■■■■■■☆☆☆☆■■■■■■☆☆☆☆ 
☆█┏━━━━━┓█☆☆☆☆☆☆■■■■■■☆☆☆☆☆■■■■■■■☆☆☆ 
☆█■专业顶贴证■█☆☆☆☆☆■■■■■■☆☆☆☆☆☆☆■■■■■■■☆☆ 
☆█ 中国顶贴协会 █☆☆☆☆■■■■■■☆☆☆☆☆☆☆☆☆■■■■■■☆☆ 
☆█ ☆荣誉颁发☆ █☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆ 
☆█■专业灌水证■█☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆ 
☆█ ☆荣誉颁发☆ █☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆ 
☆█■国家顶贴证■█☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆ 
☆█┗━━━━━┛█☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆ 
☆█████████☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆

回复列表 (共8个回复)

沙发

顶!!!

板凳

顶一下。

3 楼

再顶一下。

4 楼

第三次顶一下。

5 楼


顶破了

6 楼

好了好了。。。。。。。

7 楼


顶破了吗?我来补!

8 楼

我写的eatpuz.pas:

program lx;
  var
    s:array[1..21] of longint;
    s2:array[1..21] of boolean;
    m,n,i,k,sum,c,count:longint;
  begin
    randomize;
    fillchar(s,sizeof(s),0);
    readln(m,n);
    for i:=1 to n do read(s[i]);
    for i:=1 to 1000 do begin
      sum:=0;
      count:=0;
      fillchar(s2,sizeof(s2),false);
      repeat
        k:=random(n)+1;
        if s2[k]=false then begin
          s2[k]:=true;
          sum:=sum+s[k];
          if sum>m then begin
            sum:=sum-s[k];
            s2[k]:=false;
            count:=count+1;
          end;
        end;
      until count=500;
      if sum>c then c:=sum;
    end;
    writeln(c);
  end.

我来回复

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