Wiki下象棋 记一道广搜题

题目描述
Wiki的业余爱好就是下象棋,他不仅会下中国象棋,还会下国际象棋。他发现中国象棋和国际象棋虽然都有"马"这个棋子,但走的规则却不太一样。
国际象棋的"马"可以走"日"字,也就是说每一步只可以水平或垂直移动一点,再按对角线方面向左或者右移动(另一种解释,可以先在水平/竖直方向走两格,然后在竖直/水平方向走一格)。另外,马不允许跳出界外,也即必须跳完一步之后仍在棋盘上。如图所示:

中国象棋的"马"的走法也是走日字,在没有障碍物的情况下,其走法与国际象棋一样。唯一不同的是,如果马走了一格就遇到障碍物,马就不能继续向这个方向前进了(又称为"马脚")。如图所示,左上角的马因为没有障碍物,可以走八个方向,而右下角的马由于正上方有一个其他棋子,因此就不能往上方的两个方向跳了。

Wiki想比较一下两种马的差异,他找来了一个n行m列的大棋盘,行和列都从1开始编号。这个棋盘上已经有若干个其他棋子,马在行进的过程中不能走到这些有棋子的格子上。为了方便比较起见,假定所有棋子都在格子内部(本来中国象棋的子是放在交线上的)。Wiki先在a行b列放上国际象棋的马,算了一下它到c行d列最快要几步;又在同样的a行b列放上中国象棋的马,算了一下它到c行d列最快要几步。显然,这么手工计算很容易出错,因此Wiki想请你帮忙用程序算一下。
输入描述:
本题包含多组输入。
第一行输入一个正整数T,表示有T组输入。
每组数据的第一行包含7个数n,m,k,a,b,c,d,分别表示棋盘的行数,棋盘的列数,其他棋子的个数,起点坐标(a,b)和终点坐标(c,d)。
第二行有2k个数,每两个数代表一个其他棋子所在的坐标。数据保证不会有多个其他棋子在一个格子中,也保证(a,b)和(c,d)不会有其他棋子。

输出描述:
对于每组输入,输出一行两个数,分别是国际象棋的马和中国象棋的马从起点坐标到终点坐标最少需要走几步。若不可能到达,则输出-1。
示例1
输入
复制
2
10 10 1 5 5 5 5
1 1
2 3 1 1 1 2 3
1 2
输出
复制
0 0
1 -1

看完题目很明显是广搜题,在背前面的题目恶心完后,在比赛中写出了以下丑陋的代码:

提交总是错误,反复检查也查不出问题,终于在比赛后发现:

if(dy[i]==-2&&e[t.l+1][t.r-1]==1)continue; 
多了+1

我直接裂开。

还有一道前缀和的题也不知道怎么错的,我赶紧退学去找个工地上班😇

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;

const int N=301;
int t,n,m,k,a,b,c,d,x,y,ans1,ans2;
int v[305][305],bc[305][305],e[305][305];

int dx[8]={-2,-2,-1,-1,1,1,2,2};
int dy[8]={1,-1,2,-2,2,-2,1,-1};

class node 
{
	public :
		int l,r,w;
		node(){
			
		}
		node(int a,int b,int t)
		{
			l=a;r=b;w=t;
		}
};
void df1()
{
	queue<node>q;
	q.push(node(a,b,0));
	v[a][b]=1;
	while(!q.empty())
	{
		node t=q.front();q.pop();
		if(t.l==c&&t.r==d){
			ans1=t.w;break;
		}
		for(int i=0;i<8;++i)
		{
			x=t.l+dx[i];
			y=t.r+dy[i];
			if(x<1||y<1||x>n||y>m)continue;
			if(v[x][y])continue;
			v[x][y]=1;
			q.push(node(x,y,t.w+1));
		}
	}
} 
void df2()
{
	queue<node>q;
	q.push(node(a,b,0));
	v[a][b]=1;
	while(!q.empty())
	{
		node t=q.front();q.pop();
		if(t.l==c&&t.r==d){
			ans2=t.w;break;
		}
		for(int i=0;i<8;++i)
		{
			x=t.l+dx[i];
			y=t.r+dy[i];
			if(x<1||y<1||x>n||y>m)continue;
			if(v[x][y])continue;
			if(dx[i]==2&&e[t.l+1][t.r]==1)continue;
			if(dx[i]==-2&&e[t.l-1][t.r]==1)continue;
			if(dy[i]==2&&e[t.l][t.r+1]==1)continue;
			if(dy[i]==-2&&e[t.l][t.r-1]==1)continue; 
			v[x][y]=1;
			q.push(node(x,y,t.w+1));
		}
	}
} 

int main()
{
    cin>>t;
    while(t--)
    {
    	cin>>n>>m>>k>>a>>b>>c>>d;
    	ans1=-1;ans2=-1;
    	for(int i=0;i<=N;++i)
    	{
    		for(int j=0;j<=N;++j){
    			bc[i][j]=0;v[i][j]=0;e[i][j]=0;
    		}
    	}
    	while(k--)
    	{
    		cin>>x>>y;
    		bc[x][y]=1;v[x][y]=1;e[x][y]=1;
    	}
    	if(a==c&&b==d)
    	{
    		cout<<0<<" "<<0<<endl;
    		continue;
    	}
    	df1();
    	for(int i=0;i<=N;++i)
    	{
    		for(int j=0;j<=N;++j){
    			v[i][j]=0;
    		}
    	}
    	for(int i=0;i<=N;++i)
    	{
    		for(int j=0;j<=N;++j){
    			v[i][j]=bc[i][j];
    		}
    	}
    	df2();
    	cout<<ans1<<" "<<ans2<<endl;
    }
}

posted @ 2022-11-17 23:02  林动  阅读(18)  评论(0编辑  收藏  举报