国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

ACM 廣搜優先 Knight Moves

2019-11-14 12:43:23
字體:
來源:轉載
供稿:網友

寒假訓練二里面的A題,搜了一下發現題庫居然還有一題名字一樣的。

正好方法也差不多,所以順便就一起寫了。(廣搜優先)

TOJ 1133: Knight Moves

描述

A friend of you is doing research on the Traveling Knight PRoblem (TKP) where you are to find the shortest closed tour of knight moves that visits each square of a given set of n squares on a chessboard exactly once. He thinks that the most difficult part of the problem is determining the smallest number of knight moves between two given squares and that, once you have accomplished this, finding the tour would be easy.Of course you know that it is vice versa. So you offer him to write a program that solves the "difficult" part.Your job is to write a program that takes two squares a and b as input and then determines the number of knight moves on a shortest route from a to b.

輸入

The input will contain one or more test cases. Each test case consists of one line containing two squares separated by one space. A square is a string consisting of a letter (a-h) representing the column and a digit (1-8) representing the row on the chessboard.

輸出

For each test case, print one line saying "To get from xx to yy takes n knight moves.".

樣例輸入

樣例輸出

題目意思:有一顆棋子A走到B需要幾步。以下用的是廣搜,還有用棧的地方我詳細解說了。

#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;int c[9][9];int dir[8][2] = {{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2}};//8種走法 typedef struct{    int x,y,count;}node;node start,finish;int bfs(){    memset(c,0,sizeof(c));//作用等同于int c[9][9]={0};    node pre,cur;    start.count=0;    queue<node> q;//創建隊列q     q.push(start);//push(x) 將x壓入隊列的末端    c[start.x][start.y]=1;//起點走過了     while(!q.empty())//隊列非空     {        pre=q.front();//返回第一個元素(隊頂元素)        q.pop();//彈出隊列的第一個元素(隊頂元素)        if(pre.x==finish.x&&pre.y==finish.y)//走到終點了         return pre.count;        for(int i=0;i<8;i++)        {            cur.x=pre.x+dir[i][0];            cur.y=pre.y+dir[i][1];            if(cur.x<1||cur.x>8||cur.y<1||cur.y>8)continue;//出界了             if(c[cur.x][cur.y]==1)continue;//==1就是走過了 ,防止走回頭路             c[cur.x][cur.y]=1;//標記走過了             cur.count=pre.count+1;//步數+1             q.push(cur);        }    }    return -1;}int main(){    char row,end;    int col,ed;    int min;    while(scanf("%c%d %c%d",&row,&col,&end,&ed)!=EOF)    {    	getchar();         start.x = row-'a'+1;        start.y = col;        finish.x = end-'a'+1;        finish.y = ed;        if(start.x==finish.x&&start.y==finish.y)        min=0;        else  		min=bfs();        printf("To get from %c%d to %c%d takes %d knight moves./n",row,col,end,ed,min);    }    return 0;}

下面這題差不多,都是數字還簡單點了...用的也是廣搜優先。

然后在我百度的時候搜到一篇講這個的,感覺很不錯,因為他化簡了。

還沒拿到轉載權..就貼個地址吧...

http://blog.csdn.net/nameofcsdn/article/details/52025142

TOJ  2481: Knight Moves

描述

BackgroundMr Somurolov, fabulous chess-gamer indeed, asserts that no one else but him can move knights from one position to another so fast. Can you beat him?The Problem Your task is to write a program to calculate the minimum number of moves needed for a knight to reach one point from another, so that you have the chance to be faster than Somurolov.For people not familiar with chess, the possible knight moves are shown in Figure 1.

輸入

The input begins with the number n of scenarios on a single line by itself.Next follow n scenarios. Each scenario consists of three lines containing integer numbers. The first line specifies the length l of a side of the chess board (4 <= l <= 300). The entire board has size l * l. The second and third line contain pair of integers {0, ..., l-1}*{0, ..., l-1} specifying the starting and ending position of the knight on the board. The integers are separated by a single blank. You can assume that the positions are valid positions on the chess board of that scenario.

輸出

For each scenario of the input you have to calculate the minimal amount of knight moves which are necessary to move from the starting point to the ending point. If starting point and ending point are equal,distance is zero. The distance must be written on a single line.

樣例輸入

樣例輸出

題目意思:(數據代入說明)有3組數據,第一組數據,棋盤大小8*8,從(0,0)走到(7,0)需要5步。

這個是直接改的上面的代碼。就是在判斷出界的時候把>改成>=。

#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;int c[301][301];//棋盤最大300 int m,dir[8][2]={{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2}};//8種走法 typedef struct{    int x,y,count;}node;node start,finish;int bfs(){    memset(c,0,sizeof(c));//作用等同于int c[301][301]={0};    node pre,cur;    start.count=0;    queue<node> q;//創建隊列q     q.push(start);//push(x) 將x壓入隊列的末端    c[start.x][start.y]=1;//起點走過了     while(!q.empty())//隊列非空     {        pre=q.front();//返回第一個元素(隊頂元素)        q.pop();//彈出隊列的第一個元素(隊頂元素)        if(pre.x==finish.x&&pre.y==finish.y)//走到終點了         return pre.count;        for(int i=0;i<8;i++)        {            cur.x=pre.x+dir[i][0];            cur.y=pre.y+dir[i][1];            if(cur.x<0||cur.x>=m||cur.y<0||cur.y>=m)continue;//出界了  這里改了>=m             if(c[cur.x][cur.y]==1)continue;//==1就是走過了 ,防止走回頭路             c[cur.x][cur.y]=1;//標記走過了             cur.count=pre.count+1;//步數+1             q.push(cur);        }    }    return -1;}int main(){    int min,n;    scanf("%d",&n);    while(n--)    {	 scanf("%d %d %d %d %d",&m,&start.x,&start.y,&finish.x,&finish.y);        if(start.x==finish.x&&start.y==finish.y)        min=0;        else  		min=bfs();        printf("%d/n",min);    }    return 0;}

然后我在網上找了個簡潔版...

#include<cstdio>#include<cstring>#include<queue>using namespace std;const int dir[8][2]={{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2}};struct node{int x,y,step;};bool used[301][301];int n;int startx,starty,endx,endy;node cur,pre;int bfs(){    int i,x,y;    queue<node>que;    cur.x=startx,cur.y=starty,cur.step=0;    memset(used,0,sizeof(used));    used[startx][starty]=1;    que.push(cur);    while(!que.empty())    {        cur=que.front(),que.pop();        if(cur.x==endx&&cur.y==endy)        return cur.step;        for(i=0;i<8;i++)        {            x=cur.x+dir[i][0];            y=cur.y+dir[i][1];            if(x>=0&&x<n&&y>=0&&y<n&&!used[x][y])            {                used[x][y]=1;                pre.x=x,pre.y=y,pre.step=cur.step+1;                que.push(pre);            }        }    }    return -1;}int main(){    int tCase;    scanf("%d",&tCase);    while(tCase--)    {        scanf("%d",&n);        scanf("%d%d%d%d",&startx,&starty,&endx,&endy);        printf("%d/n",bfs());    }    return 0;}


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 望谟县| 拜城县| 永新县| 冕宁县| 昌乐县| 平潭县| 洪湖市| 怀化市| 天等县| 山西省| 偏关县| 榆社县| 龙海市| 桐庐县| 中江县| 清镇市| 宣武区| 安庆市| 宽城| 兴仁县| 平阴县| 惠水县| 邵阳市| 阳城县| 泗水县| 旺苍县| 定结县| 漳平市| 万安县| 砀山县| 马山县| 兴安县| 潍坊市| 财经| 琼中| 葫芦岛市| 巴里| 上饶市| 神农架林区| 武穴市| 凤翔县|