传送门
题目大意
给出一个n*m的地图,‘.’代表黄金,‘#’代表障碍,小明可以走到含有黄金的区域然后将黄金收集起来,而且小明只能向右或向下走。一开始小明随机出现在某个区域(当然不可能是‘#’区域),然后小明想要将所有的黄金都拿到。小明可以安放传送门,传送起始点和终点位置固定,但传送次数无限,现在问小明最少 安放 多少次传送门才能将所有的黄金都收集起来。
思路
看到这题,最直接的想法应该是在地图上能不能找到一条路径可以避开障碍且遍历所有的黄金,很显然,不行。因为只能向右或向下走,一次性走最远的长度也就是n+m-1,这时候已经回不了头只能用传送门了。也就是说,当小明无法移动的时候需要依靠传送门。那么,怎样才算不能移动呢?就是小明所在位置的右边和下面同时为障碍的时候小明是动不了的,以及整张地图的最下角不能移动。这么说可能有些读者还是会难以理解,比如说 走到无法移动的点的时候黄金刚好收集完了不就结束了? 其实题目还有一句话,就是小明开始出现的区域是随机的,而我们要考虑至少安放多少传送门,如果一开始小明出现在右下角或者在右边和下面同时有障碍的黄金点时,这时候必须依靠传送门。所以,大体的想法就是去找有多少个这样无法移动的区域。但是,如果整张地图只有0个或者1个黄金呢?这时候根本就不用传送门,直接来到起点就全搜集完了,这种情况答案是0。
代码
#include<bits/stdc++.h>
using namespace std;
char ma[1005][1005];
int main(){
int n,m;
while (cin>>n>>m){
for (int i=1;i<=n;i++){
for (int j=1;j<=m;j++){
cin>>ma[i][j];
}
}
int cnt=0,num=0;
for (int i=1;i<=n;i++){
for (int j=1;j<=m;j++){
if (ma[i][j]=='.'){
cnt++;
if ((i==n||ma[i+1][j]=='#')&&(j==m||ma[i][j+1]=='#')) num++; //寻找无法移动的点
}
}
}
if (cnt<=1) cout<<0<<endl;
else cout<<num<<endl;
}
return 0;
}