P8642

路径之谜

题目描述

小明冒充 \(X\) 星球的骑士,进入了一个奇怪的城堡。

城堡里边什么都没有,只有方形石头铺成的地面。

假设城堡地面是 \(n\times n\) 个方格。如图所示。

按习俗,骑士要从西北角走到东南角。

可以横向或纵向移动,但不能斜着走,也不能跳跃。

每走到一个新方格,就要向正北方和正西方各射一箭。

(城堡的西墙和北墙内各有 \(n\) 个靶子)

同一个方格只允许经过一次。但不必做完所有的方格。

如果只给出靶子上箭的数目,你能推断出骑士的行走路线吗?

有时是可以的,比如如图中的例子。

本题的要求就是已知箭靶数字,求骑士的行走路径(测试数据保证路径唯一)

输入格式

第一行一个整数 \(N(0<N<20)\),表示地面有 \(N \times N\) 个方格。

第二行 \(N\) 个整数,空格分开,表示北边的箭靶上的数字(自西向东)

第三行 \(N\) 个整数,空格分开,表示西边的箭靶上的数字(自北向南)

输出格式

一行若干个整数,表示骑士路径。

为了方便表示,我们约定每个小格子用一个数字代表,从西北角开始编号 $:0,1,2,3 \cdots $。

比如,图中的方块编号为:

0  1  2  3
4  5  6  7
8  9  10 11
12 13 14 15

样例 #1

样例输入 #1

4
2 4 3 4
4 3 3 3

样例输出 #1

0 4 5 1 2 3 7 11 10 9 13 14 15

裸DFS

错了一个点 86pts

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
int a[25],b[25];
int vis[25][25];
int jl[625],cnt;
int dx[4]= {1,0,-1,0};
int dy[4]= {0,1,0,-1};
int check() {
	for(int i=1; i<=n; i++)
		if(a[i]||b[i])return false;
	return true;
}
void dfs(int x,int y) {
	if(x==n&&y==n) {
		if(!check())return ;
		for(int i=1; i<=cnt; i++)
			cout<<jl[i]<<" ";
		cout<<"\n";
		exit(0);
	}
	for(int i=0; i<4; i++) {
		int nx=x+dx[i],ny=y+dy[i];
		if(nx>=1&&nx<=n&&ny>=1&&ny<=n&&!vis[nx][ny]) {
			int h=nx,l=ny;
			if(a[l]>0&&b[h]>0) {
				vis[nx][ny]=1;
				a[l]--,b[h]--;
				cnt++;
				jl[cnt]=n*(h-1)+l-1;
				dfs(nx,ny);
				a[l]++,b[h]++;
				cnt--;
				vis[nx][ny]=0;
			}
		}
	}
}
signed main() {
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1; i<=n; i++)cin>>a[i];
	for(int i=1; i<=n; i++)cin>>b[i];
	jl[++cnt]=0;
	a[1]--,b[1]--;
	dfs(1,1);
	return 0;
}
posted @ 2023-03-25 10:24  N0zoM1z0  阅读(9)  评论(0编辑  收藏  举报