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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Knight Moves(信息学奥赛一本通-T1450)

發布時間:2025/3/17 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Knight Moves(信息学奥赛一本通-T1450) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【題目描述】

編寫一個程序,計算一個騎士從棋盤上的一個格子到另一個格子所需的最小步數。騎士一步可以移動到的位置由下圖給出。


【輸入】

第一行給出騎士的數量 n。

在接下來的 3n 行中,每 3 行描述了一個騎士。其中,第一行一個整數 L 表示棋盤的大小,整個棋盤大小為 L×L;

第二行和第三行分別包含一對整數 (x,y),表示騎士的起始點和終點。假設對于每一個騎士,起始點和終點均合理。

【輸出】

對每一個騎士,輸出一行一個整數表示需要移動的最小步數。如果起始點和終點相同,則輸出 0

【輸入樣例】

3
8
0 0
7 0
100
0 0
30 50
10
1 1
1 1

【輸出樣例】

5
28
0

思路:

BFS 板子題,與 Knight Moves(信息學奧賽一本通-T1257)一個題

下面給出一種 BFS 的優化做法,可以極大加快搜索速度,即:雙向BFS

設置兩個隊列 posQ 和 negQ,分別代表從起點開始搜索的隊列和從終點開始搜索的隊列

對于判重數組 vis[i][j],我們設置三個狀態:未被訪問時為 0,正向搜索到時設為 1,逆向搜索到時設為 2

這樣一來,當正向搜索到 vis[i][j]=2 或逆向搜索到 vis[i][j]=1 時,說明終點起點相遇,此時記錄兩者步數輸出即可

此時的步數即為相遇時起點到該點的距離 dis[nx][ny]+dis[x][y]+1

【源程序】

#include<iostream> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<cmath> #include<ctime> #include<algorithm> #include<utility> #include<stack> #include<queue> #include<vector> #include<set> #include<map> #include<bitset> #define PI acos(-1.0) #define INF 0x3f3f3f3f #define LL long long #define Pair pair<int,int> LL quickPow(LL a,LL b){ LL res=1; while(b){if(b&1)res*=a; a*=a; b>>=1;} return res; } LL multMod(LL a,LL b,LL mod){ a%=mod; b%=mod; LL res=0; while(b){if(b&1)res=(res+a)%mod; a=(a<<=1)%mod; b>>=1; } return res%mod;} LL quickMultPowMod(LL a, LL b,LL mod){ LL res=1,k=a; while(b){if((b&1))res=multMod(res,k,mod)%mod; k=multMod(k,k,mod)%mod; b>>=1;} return res%mod;} LL quickPowMod(LL a,LL b,LL mod){ LL res=1; while(b){if(b&1)res=(a*res)%mod; a=(a*a)%mod; b>>=1; } return res; } LL getInv(LL a,LL mod){ return quickPowMod(a,mod-2,mod); } LL GCD(LL x,LL y){ return !y?x:GCD(y,x%y); } LL LCM(LL x,LL y){ return x/GCD(x,y)*y; } const double EPS = 1E-6; const int MOD = 1000000000+7; const int N = 1000+5; const int dnewStr[] = {0,0,-1,1,1,-1,1,1}; const int dy[] = {1,-1,0,0,-1,1,-1,1}; using namespace std;struct Node {int x, y;Node() {}Node(int x, int y) : x(x), y(y) {} }; int n; int vis[N][N]; int dis[N][N]; int dir[8][2] = {{-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}, {1, 2}, {2, 1}, {2, -1}, {1, -2}}; void BFS(Node st, Node ed) {if (st.x == ed.x && st.y == ed.y) {printf("0\n");return;}memset(dis, 0, sizeof(dis));memset(vis, 0, sizeof(vis));queue<Node> posQ; //正向隊列queue<Node> negQ; //反向隊列posQ.push(st);negQ.push(ed);vis[st.x][st.y] = 1;vis[ed.x][ed.y] = 2;while (!posQ.empty() || !negQ.empty()) {if (!posQ.empty()) {Node now = posQ.front();posQ.pop();int x = now.x;int y = now.y;for (int i = 0; i < 8; i++) {int nx = x + dir[i][0];int ny = y + dir[i][1];if (nx < 0 || ny < 0 || nx >= n || ny >= n)continue;if (vis[nx][ny] == 2) { //相遇int step = dis[x][y] + dis[nx][ny] + 1;printf("%d\n", step);return;} if (vis[nx][ny] == 0) {vis[nx][ny] = 1;dis[nx][ny] = dis[x][y] + 1;posQ.push(Node(nx, ny));}}}if (!negQ.empty()) {Node now = negQ.front();int x = now.x;int y = now.y;for (int i = 0; i < 8; i++) {int nx = now.x + dir[i][0];int ny = now.y + dir[i][1];if (nx < 0 || ny < 0 || nx >= n || ny >= n)continue;if (vis[nx][ny] == 1) { //相遇int step = dis[nx][ny] + dis[x][y] + 1;printf("%d\n", step);return;} if (vis[nx][ny] == 0) {vis[nx][ny] = 2;dis[nx][ny] = dis[x][y] + 1;negQ.push(Node(nx, ny));}}}} } int main() {int t;scanf("%d", &t);while (t--) {scanf("%d", &n);Node st, ed;scanf("%d%d%d%d", &st.x, &st.y, &ed.x, &ed.y);BFS(st, ed);}return 0; }

?

總結

以上是生活随笔為你收集整理的Knight Moves(信息学奥赛一本通-T1450)的全部內容,希望文章能夠幫你解決所遇到的問題。

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