poj 2488

来源:互联网 发布:如何写好毛笔字 知乎 编辑:程序博客网 时间:2024/06/06 01:31

这道题是图论深搜的典型题。初做此题,首先觉得应当有一个邻接矩阵,于是花了很大力气将棋盘编号,最后在判断是否邻接的条件处纠结许久。

之后的搜索使用了C++的栈结构,没有使用递归(优点),但最后无论时间、代码长度、还是空间都不理想。经过学习网上大牛们的代码后,恍然

大悟,原来根本不需要构建邻接矩阵,只能说我学的太死了,完全可以使用二维数组直接模拟马的跳跃,这样判断邻接的问题就没有了。

#include <iostream>#include <stdio.h>#include <stdlib.h>#include <stack>#include <string.h>using namespace std;int main(){    char board[26][26];    int num = 0;    scanf("%d",&num);    for(int i = 1;i <= num;i++)    {        int xMax,yMax;        scanf("%d %d",&xMax,&yMax);        //printf("%d %d",xMax,yMax);        memset(board,0,sizeof(board));        int boardSize = xMax * yMax;        for(int j = 0;j < boardSize;j++)        {            if((j + xMax + 2) < boardSize && ((j % xMax + 2) < xMax))                board[j][(j + xMax + 2)] = 1;            if((j + xMax - 2) < boardSize && (j + xMax - 2) >= 0 && (j % xMax - 2) >= 0)                board[j][(j + xMax - 2)] = 1;            if((j - xMax + 2) < boardSize && (j - xMax + 2) >= 0 && (j % xMax + 2) < xMax)                board[j][(j - xMax + 2)] = 1;            if((j - xMax - 2) >= 0 && (j % xMax - 2) >= 0)                board[j][(j - xMax - 2)] = 1;            if((j + 2 * xMax + 1) < boardSize && (j % xMax + 1) < xMax)                board[j][(j + 2 * xMax + 1)] = 1;            if((j + 2 * xMax - 1) < boardSize && (j + 2 * xMax - 1) >= 0 && (j % xMax - 1) >= 0)                board[j][(j + 2 * xMax - 1)] = 1;            if((j - 2 * xMax + 1) < boardSize && (j - 2 * xMax + 1) >= 0 && (j % xMax + 1) < xMax)                board[j][(j - 2 * xMax + 1)] = 1;            if((j - 2 * xMax - 1) >= 0 && (j % xMax - 1) >= 0)                board[j][(j - 2 * xMax - 1)] = 1;        }        char visited[26];        memset(visited,0,sizeof(visited));        bool flag = false;        for(int k = 0;k < boardSize;k++)        {            memset(visited,0,sizeof(visited));            stack<int> s;            s.push(k);            visited[k] = 1;            int startFrom = 0;            int record[26];            memset(record,0,sizeof(record));            int recordNum = 1;            flag = false;            if(boardSize == 1)            {                flag = true;                printf("Scenario #%d:\nA1\n\n",i);                break;            }            while(!s.empty())            {                int current = s.top();                int j;                for(j = startFrom;j < boardSize;j++)                {                    if((board[current][j] == 1) && visited[j] == 0)                    {                        s.push(j);                        visited[j] = 1;                        startFrom = 0;                        record[recordNum] = j;                        recordNum++;                        if(recordNum == boardSize)                            flag = true;                        break;                    }                }                if(flag)                    break;                if(j == boardSize)                {                    startFrom = s.top() + 1;                    visited[startFrom - 1] = 0;                    s.pop();                    recordNum--;                }            }            if(flag)            {                printf("Scenario #%d:\n",i);                for(int j = 0;j < recordNum;j++)                    printf("%c%d",record[j] / xMax + 'A',record[j] % xMax + 1);                printf("\n\n");                break;            }        }        if(!flag)            printf("Scenario #%d:\nimpossible\n\n",i);    }    return 0;}

阅读过带给我改进灵感的代码:

#include <iostream>using namespace std;int step[8][2]={{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};int main(){int a,b,ch[26][26],ss[26*26][3],s,p,x,y,j,xx,yy,ci=0;cin>>a;while(cin>>b>>a){memset(ch,0,sizeof(ch));p=a*b-1;s=0;ch[0][0]=1;//visitx=0;y=0;j=0;while(s>=0){if (j<8)for (;j<8;j++){xx=x+step[j][0];yy=y+step[j][1];if (ch[xx][yy]==0 && xx>=0 && xx<a && yy>=0 && yy<b){ss[s][0]=x+65;x=xx;ss[s][1]=y+1;y=yy;ss[s][2]=j;s++;ch[xx][yy]=1;j=0;break;}}if (s==p)break;if (j==8){s--;if (s>=0){ch[x][y]=0;x=ss[s][0]-65;y=ss[s][1]-1;j=ss[s][2]+1;}}}++ci;printf("Scenario #%d:\n",ci);if (s==p){for (p=0;p<s;p++)cout<<char(ss[p][0])<<ss[p][1];x+=65;cout<<char(x)<<y+1;}elsecout<<"impossible";cout<<endl<<endl;}return 0;}