poj 2488

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

之后的搜索使用了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;//visit
		x=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;
		}
		else
			cout<<"impossible";
		cout<<endl<<endl;
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值