ImageVerifierCode 换一换
格式:DOCX , 页数:49 ,大小:27.07KB ,
资源ID:26248101      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/26248101.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(POJ搜索题目题解.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

POJ搜索题目题解.docx

1、POJ搜索题目题解poj搜索题总结初期篇 简单搜索(1)深度优先搜索 (poj2488,poj3009,poj1321)(2)广度优先搜索 (poj3278,poj1426,poj3126,poj3087.poj3414,poj2251,poj3083)(3)简单搜索技巧和剪枝(poj2531,poj1416,poj2676,1129) 看到这些题是不是很眼熟。没错,这就是某位大牛推荐初期要做的题。而这文章就是为这些题加上解题报告以及一些总结。 深度优先搜索poj2488:A Knights Journey 如果没有按字典序输出这个要求的话,就是简单的DFS,但是加上的话,就是麻烦题。这就要求

2、求出全部的走法或在行走时,按照某种顺序走。从时间上来说,当然是选择第二种了。若存在可行路线,则每个格子必然都走过。所以从A1开始,按照某种顺序走,若有解,则为所求,若无,则无解。/WA了N次,才发现是倒在字典序的手下/虽然题目没说,但是这道题最后一组数据后是没有空行的.否则会PE./若存在可行路线,则每个格子都走过。所以从(0,0)开始即可,不需要遍历每一个起始点/注意行走的方法(即MOV数组元素的排列),可以在找到可行解时,就使得其字典序最小 #include#include#include using namespace std; bool flag;string answer30;int

3、 chess3030; /这个的设置一定要与下面的转换相对应,之前就是不对应,错了N次int mov82=-1,-2,1,-2,-2,-1,2,-1,-2,1,2,1,-1,2,1,2; string GetPosition(int x,int y) /将X,Y坐标转换成题目要求的形式 string stmp; stmp+=(char)(y+A); /由于先出现的是Y坐标(如B3),所以MOV数组中的Y应从-2到2的顺序变化 stmp+=(char)(x+1); return stmp; void SaveIt(int p,int q) /保存下答案 for(int i=0;ip;+i) fo

4、r(int j=0;jq;+j) answerchessij=GetPosition(i,j); void dfs(int p,int q,int num,int x,int y) if( num=p*q ) flag=true; SaveIt(p,q); return; int xx,yy; for(int i=0;i=0 & xx=0 & yycases; while( cases- ) cinpq; flag=false; memset(chess,0,sizeof(chess); chess00=1; dfs(p,q,1,0,0); /output coutScenario #coun

5、t+:endl; if( flag ) for(i=1;i=p*q;+i) coutansweri; coutendl; else coutimpossibleendl; if( cases!=0 ) coutendl; return 0; poj1321:棋盘问题这题是简单的DFS,但题目有个地方说得不是很清楚,就是以“#”为标志的位置才能放棋子。/一次AC,用了DFS,以递归回溯的形式实现题目说得有点不清楚,以“#”为标志的位置才能入棋子 #include#include using namespace std; int count;int chess88; /能放棋子为1,不能为0,放下

6、棋子的是2 bool IsLegal(int x,int y) /由于一行只放一个,所以不用判断是否同行,这里只判断是否同列 for(int i=0;ix;+i) if( chessiy=2 ) return false; return true; void dfs(int n,int k,int num,int start) /num表示当前放了几颗棋子,START表示放棋子的超始行数 if( num=k ) +count; return ; for(int i=start;in;+i) for(int j=0;jnk & n!=-1 ) memset(chess,0,sizeof(ches

7、s); for(int i=0;in;+i) /get input for(int j=0;jctmp; if( ctmp=# ) chessij=1; count=0; dfs(n,k,0,0); coutcountendl; return 0; 广度优先搜索DFS一般是用来求全部解。但可以使其按照某种方式前进而达到求最优解的目的。而BFS则常用于求最优解,但其缺陷是空间要求过大。用BFS还有一个易错点,就是队列空间申请得过小(特别是用循环数组),导致有一些情况判断来不及判断就被覆盖掉。POJ 1321: Catch That Cow这题如果是用循环数组做的话,一定要注意我说的那个易错点。

8、/做BFS的第一题(用了类,STL中的队列),写完后,提交,TLE = =不用STL中的队列再加上剪枝后,就不TLE了,但一直RE = =(数组越界)不RE,然后又WA,发现这情况:0 100000 不能判断因为队列数组开得太小了,把还没来得及处理的数据给覆盖掉了改大后,才AC掉,阴险题#include/#include using namespace std; const int QMAX=50000; class NODE public: NODE(int xx=0,int ss=0):x(xx),step(ss) int x; int step; bool walk200001; /数组

9、一定要足够大,否则RENODE qQMAX; /队列int move32= 1,1,1,-1,2,0 ; /移动的方法 int main() / ifstream cin(test.in); int s,t,now,total,itmp; while( cinst ) now=0; total=1; memset(walk,0,sizeof(walk); /BFS qnow=NODE(s,0); walks=true; while( now!=total ) if( qnow%QMAX.x=t ) coutqnow%QMAX.stependl; break; for(int i=0;i3;+i

10、) itmp=(qnow%QMAX.x*movei0)+movei1; if( itmp=0 & !walkitmp ) /先判断ITMP范围,否则RE walkitmp=true; q(total+)%QMAX=NODE(itmp,qnow%QMAX.step+1); +now; return 0; POJ 1426:Find The Multiple#include#include/#include using namespace std; const int QMAX=10000; /定义队列最大长度 bool IsMultiple(string str,int n) /判断STR能否被

11、N整除 int len,mul,itmp; mul=10; itmp=0; len=str.size(); for(int i=0;ilen;+i) itmp=itmp*mul+(stri-0); if( itmpn & n!=0 ) now=0; total=1; /bfs qnow=1; while( now!=total ) if( IsMultiple(qnow%QMAX,n) ) coutqnow%QMAXendl; break; for(int i=0;i2;+i) q(total+)%QMAX=qnow%QMAX+letteri; +now; return 0; POJ 3126

12、 Prime Path也可以说是简单的BFS题。但有一点是注意的是SQRT函数可是被重载过。使用时,一定要指明其类型。BFS题,先求出全部四位的素数,然后再逐个尝试提交后CE,原来是SQRT函数作怪然后是WA,原因是素数判断错误,应该是J=SQRT(I),而不是JSQRT(I)修改后AC #include#include/#include using namespace std; class NODE public: NODE(int nn=0,int ss=0):num(nn),step(ss) int num; int step; const int PMAX=2000;const int

13、 QMAX=9000;int primePMAX;bool selectPMAX;NODE qQMAX; void init(int& len) /算出全部的素数 bool flag; for(int i=1000;i9999;+i) flag=true; for(int j=2;j1 ) return false; num1/=10; num2/=10; return true; int main() / ifstream cin(test.in); bool flag; int cases,n,m,len(0),now,total; init(len); cincases; while(

14、cases- ) cinnm; memset(select,0,sizeof(select); /bfs now=0; total=1; flag=false; qnow=NODE(n,0); while( now!=total ) if( qnow%QMAX.num=m ) coutqnow%QMAX.stependl; flag=true; break; for(int i=0;ilen;+i) if( !selecti & IsLegal(qnow%QMAX.num,primei) ) q(total+)%QMAX=NODE(primei,qnow%QMAX.step+1); selec

15、ti=true; +now; if( !flag ) coutImpossibleendl; return 0; POJ 3414:Pots相比起之前的BFS题,不同点就只有输出路径。这时只要在类中多加一个变量来记录上一步是哪个步骤。但要注意,不要用循环数组,因为会把前面的一些值给覆盖掉。/bfs,简单题,注意怎样回溯出使用了哪些步骤就可以了/第一次WA,不能过的数据:91 100 95 答案是170/错误原因:walk数组开小了,导致有一些情况不能判断/从100X100改为201X201后就AC了#include#include#include#include using namespace

16、 std; const int QMAX=9000; class NODE public: NODE(int x1=0,int x2=0,int x3=0,int x4=0):a(x1),b(x2),method(x3),pre(x4) int a; int b; int method; /记录是用什么方法得到这步 int pre; /记录前一个步骤是哪个(数组的下标),回溯时用到; NODE qQMAX; /队列数组开大点,不要用循环数组bool walk201201; /注意最大应该是200,就是这里开小了,导致WAstring str7= ,FILL(1),FILL(2),DROP(1)

17、,DROP(2),POUR(1,2),POUR(2,1) ; int main() ifstream cin(test.in); bool flag; int a,b,c,now,total,count; while( cinabc ) memset(walk,0,sizeof(walk); now=0; total=1; flag=false; walk00=true; qnow=NODE(0,0,0,0); while( now!=total ) if( qnow.a=c | qnow.b=c ) flag=true; break; /fill if( qnow.a!=a & !walka

18、qnow.b) /method=1 means FILL(1) qtotal+=NODE(a,qnow.b,1,now); walkaqnow.b=true; if( qnow.b!=b & !walkqnow.ab ) /method=2 means FILL(2) qtotal+=NODE(qnow.a,b,2,now); walkqnow.ab=true; /drop if( qnow.a!=0 & !walk0qnow.b) /method=3 means DROP(1) qtotal+=NODE(0,qnow.b,3,now); walk0qnow.b=true; if( qnow.

19、b!=0 & !walkqnow.a0 ) /method=4 means DROP(2) qtotal+=NODE(qnow.a,0,4,now); walkqnow.a0=true; /pour if( qnow.a!=0 & qnow.b!=b ) /method=5 means POUR(1,2) if( qnow.a+qnow.b=b & !walkqnow.a-(b-qnow.b)b ) qtotal+=NODE(qnow.a-(b-qnow.b),b,5,now); walkqnow.a-(b-qnow.b)b=true; else if( qnow.a+qnow.b=a & !

20、walkaqnow.b-(a-qnow.a) ) qtotal+=NODE(a,qnow.b-(a-qnow.a),6,now); walkaqnow.b-(a-qnow.a)=true; else if( qnow.a+qnow.ba & !walkqnow.a+qnow.b0 ) qtotal+=NODE(qnow.a+qnow.b,0,6,now); walkqnow.a+qnow.b0=true; +now; if( flag ) count=0; stack sta; while( now!=0 ) /使用堆栈来存放步骤 +count; sta.push(strqnow.method

21、); now=qnow.pre; coutcountendl; while( !sta.empty() ) coutsta.top()endl; sta.pop(); else coutimpossibleendl; return 0;1606 POJ 3087:Shufflem Up在SHUFFLE时只有一种情况是合法,就是S2只能在下面。其它就是简单的BFS了。/第一道一次AC的BFS,注意在SHUFFLE时,只能S2在下面,即不会出现S1在下面的情况#include#include#include using namespace std; class NODE public: NODE(

22、string ss=,int is=0):str(ss),step(is) string str; int step; const int QMAX=9000;NODE qQMAX; string Shuffle(string s1,string s2) string tmp; for(int i=0;is1.size();+i) tmp+=s2i; tmp+=s1i; return tmp; void GetS1AndS2(string str,string& s1,string& s2) /get s1 and s2 from s12 int len=s1.size(); for(int i=0;ilen;+i) s1i=stri; for(int j=0;jlen;+j) s2j=strj+len; bool IsWalk(string str,int qlen) /is str appeared? for(int i=0;iqlen;+i) if( qi.str=str ) return true; return false; int main() ifstream

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1