日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

马走日poj java超时_简单搜索poj 2243(水

發布時間:2025/5/22 编程问答 12 豆豆
生活随笔 收集整理的這篇文章主要介紹了 马走日poj java超时_简单搜索poj 2243(水 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

應該也不算一題多解。

就是閑的。。也是因為這題比較簡單而且在網上看了別人寫的特別好,就想用這題當入門練一下(逃

https://vjudge.net/problem/POJ-2243

題意:

8*8的棋盤,馬走斜日,馬走幾步可以達到給出的終點?

方法一:傳統BFS,就不再贅述了,很簡單啦。

#include

#include

#include

#include

#define bug cout<

using namespace std;

char a1,a2,b1,b2;

int map[8][8];

struct data{

int xi,yi;

};

int dx[8]={1,2,2,1,-1,-2,-2,-1};

int dy[8]={2,1,-1,-2,-2,-1,1,2};

int judge(data temp,int x2,int y2){

if(temp.xi==x2&&temp.yi==y2) return 1;

return 0;

}

int bfs(int x1,int y1,int x2,int y2){

memset(map,-1,sizeof(map));

queueque;

data in;

in.xi=x1;

in.yi=y1;

que.push(in);

map[in.xi][in.yi]=0;

while(!que.empty()){

data top,ou;

top=que.front();

que.pop();

if(judge(top,x2,y2)) return map[top.xi][top.yi];

for(int i=0;i<8;i++){

ou.xi=top.xi+dx[i];

ou.yi=top.yi+dy[i];

if(map[ou.xi][ou.yi]==-1&&ou.xi>=0&&ou.xi<8&&ou.yi>=0&&ou.yi<8){

que.push(ou);

map[ou.xi][ou.yi]=map[top.xi][top.yi]+1;

}

}

}

return 0;

}

int main(){

//freopen("test.txt","r",stdin);

while(cin>>a1>>a2>>b1>>b2){

int ans=bfs(a1-'a',a2-'1',b1-'a',b2-'1');

printf("To get from %c%c to %c%c takes %d knight moves.\n",a1,a2,b1,b2,ans);

}

return 0;

}

順便在這里加一個小技巧。之前有和同學說過這個。

結構體其實是可以和類一樣用的??梢苑悄J構造,如果要非默認構造的話,要記得加一個默認構造函數。

還有一個就是為什么結構體不能放在set啊,map啊里面。

因為set和map的底層是紅黑樹。紅黑樹的話他對內部對象就會排序。就要重載一下小于號。自定義一個小于號。

#include

#include

#include

#include

using namespace std;

struct data{

int x,y;

data(int dx,int dy){

x=dx,y=dy;

}

data(){}

bool operator const data b)const{

return x==b.x?xint main(){

data temp1(1,1);

data temp2(2,2);

setse;

se.insert(temp1);

se.insert(temp2);

if(se.count(temp1)) cout

}

方法二:傳統DFS。這個還真的蠻。。。有點小意思吧。而且對這道題的分類也是BFS(hhh分類的人可能是TLE了DFS

我寫了一個我認為很對的剪枝其實并沒有剪到什么(逃

我還感覺寫得蠻對的。結果TLE了兩發。。。這我就很不能理解啦。

我一開始DFS函數是這么寫的。

void dfs(int x1,int y1,int x2,int y2,int step){

if(judge(x1,y1,x2,y2)){

ans=min(ans,step);

return;

}

if(step>=ans) return;//這就是我說的沒什么用的剪枝,發現當前步數(不管找到了沒有)比ans大了就直接剪掉。其實也減到了不少,但是對這道題來說確實是。。。嗯。。不夠。

for(int i=0;i<8;i++){

int xx=dx[i]+x1;

int yy=dy[i]+y1;

if(map[xx][yy]==-1&&xx>=0&&xx<8&&yy>=0&&yy<8){

map[xx][yy]=1;

dfs(xx,yy,x2,y2,step+1);

map[xx][yy]=-1;

}

}

}

超有道理的。對不對。

隨后想到,如果我想要剪枝跟有效那我是不是要使ans迅速的變小或者使每一步都能判斷出他是否有效。

于是,如果對于一個點 map[x][y]我已經到過這個點,并且我上次到這一點的步數小于這一次的,(這是深搜嘛,廣搜就不會遇到這樣的問題。)那當前我這條路走下去肯定沒有上一次那么走棒,所以我可以對map數組進行更新,使得map數組里的值盡量地小,這樣就方便我下一次把它剪掉。

其實也很容易就想到了。

#include

#include

#include

#include

#define bug cout<

using namespace std;

char a1,a2,b1,b2;

int map[8][8];

int dx[8]={1,2,2,1,-1,-2,-2,-1};

int dy[8]={2,1,-1,-2,-2,-1,1,2};

int judge(int x1,int y1,int x2,int y2){

if(x1==x2&&y1==y2) return 1;

return 0;

}

int ans=1e9+7;

void dfs(int x1,int y1,int x2,int y2,int step){

if(judge(x1,y1,x2,y2)){

ans=min(ans,step);

return;

}

if(map[x1][y1]==-1||map[x1][y1]>step) map[x1][y1]=step;

if(map[x1][y1]return;

if(step>=ans) return;

for(int i=0;i<8;i++){

int xx=dx[i]+x1;

int yy=dy[i]+y1;

if(xx>=0&&xx<8&&yy>=0&&yy<8){

dfs(xx,yy,x2,y2,step+1);

}

}

}

int main(){

//freopen("test.txt","r",stdin);

while(cin>>a1>>a2>>b1>>b2){

memset(map,-1,sizeof(map));

map[a1-'a'][a2-'1']=1;

ans=1e9+7;

dfs(a1-'a',a2-'1',b1-'a',b2-'1',0);

printf("To get from %c%c to %c%c takes %d knight moves.\n",a1,a2,b1,b2,ans);

}

return 0;

}

因為很久沒有寫搜索了,所以。。。練個手。

這題還有很多種解法,我會陸續寫出雙向BFS,A*和純數學解法(感覺很厲害的樣子呢)。

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的马走日poj java超时_简单搜索poj 2243(水的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。