信息学奥赛一本通(1330:【例8.3】最少步数)
1330:【例8.3】最少步數
時間限制: 1000 ms ??? ??? 內存限制: 65536 KB
提交數: 10314 ??? 通過數: 5549
【題目描述】
在各種棋中,棋子的走法總是一定的,如中國象棋中馬走“日”。有一位小學生就想如果馬能有兩種走法將增加其趣味性,因此,他規定馬既能按“日”走,也能如象一樣走“田”字。他的同桌平時喜歡下圍棋,知道這件事后覺得很有趣,就想試一試,在一個(100×100)的圍棋盤上任選兩點A、B,A點放上黑子,B點放上白子,代表兩匹馬。棋子可以按“日”字走,也可以按“田”字走,倆人一個走黑馬,一個走白馬。誰用最少的步數走到左上角坐標為(1,1)的點時,誰獲勝。現在他請你幫忙,給你A、B兩點的坐標,想知道兩個位置到(1,1)點可能的最少步數。
【輸入】
A、B兩點的坐標。
【輸出】
最少步數。
【輸入樣例】
12 16 18 10【輸出樣例】
8 9【分析】
? ? ? ? 馬有 12 種不同的擴展方向∶
(1)馬走"日"∶(x-2,y-1)、(x-1,y-2)、(x-2,y+1)、(x-1,y+2)、(x+2,y-1)、(x+1,y-2)、(x+2, y+1)、(x+1,y+2)
(2)馬走"田":(x-2,y-2)、(x-2.y+2)、(x+2,y-2)、(x+2,y+2)。
表示為:
int dx[12]={-2,-2,-1,1,2,2,2,2,1,-1,-2,-2},
int dy[12]={-1,-2,-2,-2,-2,-1,1,2,2,2,2,1};
【參考代碼】
C代碼:
#include <stdio.h> #include <string.h>int dx[12]={-2,-2,-1,1,2,2,2,2,1,-1,-2,-2}; // 位移數組 int dy[12]={-1,-2,-2,-2,-2,-1,1,2,2,2,2,1};int main() {int s[101][101]; // 記錄最少步數 int que[10000][4]={0}; // 隊列數組,存儲可到達的點 int x1,y1; // 黑馬所在點 int x2,y2; // 白馬所在點int head=1,tail=1; // 初始位置入隊int i;int x,y;memset(s,-1,sizeof(s)); // s數組的初始化 que[1][1]=1;que[1][2]=1;que[1][3]=0;scanf("%d%d%d%d",&x1,&y1,&x2,&y2); // 讀入黑馬白馬的出發位置 // bfswhile(head<=tail) // 若隊列非空,則擴展隊首結點 {for(i=0;i<12;i++) // 枚舉12個擴展方向{x=que[head][1]+dx[i]; // 計算馬按 i 方向跳躍后的位置 y=que[head][2]+dy[i];if(x>0 && y>0){if(s[x][y]==-1) // 若(x,y)滿足約束條件 {s[x][y]=que[head][3]+1; // 計算(1,1)到(x,y)的最少步數 tail++; // (1,1)至(x,y)的最少步數入隊 que[tail][1]=x;que[tail][2]=y;que[tail][3]=s[x][y];if(s[x1][y1]>0 && s[x2][y2]>0) // 輸出問題的解 {printf("%d\n%d\n",s[x1][y1],s[x2][y2]);return 0;}}}}head++;}return 0; }C++代碼:
#include <iostream> #include <queue> #include <cstring>using namespace std;struct node {int x,y; // 坐標 int step; // 到該結點的步數 };int dx[12]={-2,-2,-1,1,2,2,2,2,1,-1,-2,-2}; // 位移數組 int dy[12]={-1,-2,-2,-2,-2,-1,1,2,2,2,2,1};int main() {int a[101][101]; // 記錄最少步數 int que[10000][4]={0}; // 隊列數組,存儲可到達的點 int x1,y1; // 黑馬所在點 int x2,y2; // 白馬所在點 queue <node> q; // 申請隊列 node start,news;memset(a,-1,sizeof(a)); //a數組的初始化start.x=1; // 初始化起點 start.y=1;start.step=0; q.push(start); // 起始點入隊cin>>x1>>y1>>x2>>y2; //讀入白馬和黑馬的出發位置while(!q.empty()) //若隊列非空,則擴展隊首結點{start=q.front();q.pop();for(int d=0;d<12;d++) //枚舉12個擴展方向{int newx,newy,st;newx=start.x+dx[d]; //計算馬按d方向跳躍后的位置newy=start.y+dy[d];if(newx>0 && newy>0 && newx<=100 && newy<=100){if(a[newx][newy]==-1) //若(x,y)滿足約束條件{a[newx][newy]=start.step+1; //計算(1,1)到(x,y)的最少步數news.x=newx;news.y=newy;news.step=a[newx][newy];q.push(news);if(a[x1][y1]>0 && a[x2][y2]>0) //輸出問題的解{cout<<a[x1][y1]<<endl;cout<<a[x2][y2]<<endl;return 0;}}}}}return 0; }http://ybt.ssoier.cn:8088/problem_show.php?pid=1330
新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!總結
以上是生活随笔為你收集整理的信息学奥赛一本通(1330:【例8.3】最少步数)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 信息学奥赛一本通(1088:分离整数的各
- 下一篇: 信息学奥赛一本通(1319:【例6.1】