一、题目
1、题目描述
2、输入输出
2.1输入
2.2输出
3、原题链接
二、解题报告
1、思路分析
考虑直接暴力所有合法路径
在网格上的合法移动是怎样的呢?
我们令row[i],col[j]分别为第i行、第j列墙上的箭的数目
对于题目给的箭的数目其实就是每一列每一行我们能够遍历的格子数目,所以假如当前位置为(i, j),新位置ni, nj除了满足不越界外,还要满足未访问且row[nx],col[ny]均不为0
这样暴搜即可
时间复杂度看上去蛮高的,但由于题目的限制剪掉了很多枝节,而且暴力杯(,所以不用担心超时
2、复杂度
时间复杂度:空间复杂度:O(n*n)
3、代码详解
#include <iostream>
#include <vector>
using namespace std;
vector<int> path;
int row[21], col[21], n;
bool vis[500];
constexpr int dst[5] = {1, 0, -1, 0, 1};
inline void print(){
for(auto x : path) cout << x << ' ';
}
bool check(){
for(int i = 0; i < n; i++) if(col[i] || row[i]) return false;
return true;
}
bool dfs(int x, int y){
if(x == n - 1 && y == n - 1){
if(!check()) return false;
print();
return true;
}
for(int i = 0, nx, ny; i < 4; i++){
nx = x + dst[i], ny = y + dst[i + 1];
if(nx < 0 || ny < 0 || nx >= n || ny >= n || vis[nx * n + ny]) continue;
if(!row[nx] || !col[ny]) continue;
row[nx]--, col[ny]--, vis[nx * n + ny] = 1;
path.emplace_back(nx * n + ny);
if(dfs(nx, ny)) return true;
path.pop_back();
row[nx]++, col[ny]++, vis[nx * n + ny] = 0;
}
return false;
}
int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n;
for(int i = 0; i < n; i++) cin >> col[i];
for(int i = 0; i < n; i++) cin >> row[i];
vis[0] = 1, path.emplace_back(0), row[0]--, col[0]--, dfs(0, 0);
return 0;
}