此题为 Vijos P1128(非1028),感觉度娘好像有点抽
贴出这个程序献丑了,今天早上过了一遍深搜,不怕大家笑话,深搜和广搜我还才开头呢!
把N皇后问题递归和非递归算法过了一遍后,兴致勃勃的去Vijos上找题目练手(当然仅限于1、2难度,否则几天也憋不出一道题)。
找到了P1128这道题,百度了一下是个非常经典的深搜,好,就这道题了!
由于初学深搜,思维还没有融入其中,想法很死板,不由自主的就想到用几个循环,当然还是克制住了这个想法。
仔细分析了一下题目的意思,感觉不需要判重(目前我还不会Hash),所以我觉得就是一个简单的裸搜吧,找到一个判断一次,符合条件就inc(total)。
以下是筛选的代码,可以无视:
1 procedure Judg_one(s:longint); 2 var 3 i:integer; 4 bool:boolean; 5 begin 6 bool:=true; 7 if s=2 then inc(total) 8 else begin 9 for i:=2 to (s div 2) do 10 if s mod i=0 then bool:=false; 11 if bool=true then inc(total); 12 end; 13 end;
(我做题习惯分成几个模块分别写,不知道这样算不算坏习惯)
判断神马的都是小问题,主要还是看如何通过递归回溯得到所有值。
源程序代码如下:
1 program p1128; 2 var 3 n,k,i,j,t,total:longint; 4 x:array[1..1000] of longint; 5 {===================} 6 procedure Judg_one(s:longint);【判断是否为素数】 7 var 8 i:integer; 9 bool:boolean; 10 begin 11 bool:=true; 12 if s=2 then inc(total) 13 else begin 14 for i:=2 to (s div 2) do 15 if s mod i=0 then bool:=false; 16 if bool=true then inc(total); 17 end; 18 end; 19 {===================} 20 procedure Dfs_try(t,s,p:longint);【Dfs回溯递归过程】【应该可以写成非递归,不过王大神说他写非递归循环写了好久果断放弃了】 21 var 22 q,i:longint; 23 begin 24 if p=k then begin Judg_one(s); exit end;【当p=k时,调用判断过程,退出当前递归层次】 25 for i:=t to n do 26 begin 27 s:=s+x[i]; 28 p:=p+1; 29 Dfs_try(i+1,s,p);【我觉得整个程序的精华就是这一句】 30 s:=s-x[i]; 31 p:=p-1; 32 end; 33 end; 34 {=================== main =================} 35 begin 36 read(n); 37 read(k); 【读入数据】 38 for i:=1 to n do 39 read(x[i]); 40 total:=0; 41 Dfs_try(1,0,0); 42 write(total); 【深搜结束后输出结果】 43 end.
令我感到惊喜的是竟然一次AC了!!!不容易啊,这是一个好兆头。
好了时间紧迫,去编下一道题了,今天争取多贴几道题出了,显得比较有成就感!诸位一起加油!
原文地址:http://www.vijos.org/Problem_show.asp?id=1128
QQ:85637720
By ZYT
12.10.05