题意:给你一个地图 让你从左上角到右下角 但是中间有障碍物 问你最少需要放几个障碍物才能拦住
思路:首先 答案只能是0 1 2 然后搜两遍就行了
如果第一遍到不了 就0
如果能到 看第二遍能不能到 能到就2 不能就1
当然第一遍走过的地方标记上 第二遍不能再走。
就这么简单。自己还分了好多情况 其实不必
还有一个坑!是 数组要开大一点 如果按题目要求 1e6 会re
const int maxn=3e6+10;
//深搜版
int n,m,cnt;
char mp[maxn];
bool con[maxn];
int dir[2][2]={1,0,0,1};
struct node{
int x,y;
node(){}
node(int a,int b):x(a),y(b){}
};
stack<node> stk;
inline int pos(int i,int j){//i j是正常坐标!!!
return (i-1)*m+j-1;
}
inline bool judge(int i,int j){
if(mp[pos(i,j)]=='#'||con[pos(i,j)]||i>n||j>m) return false;
return true;
}
bool dfs(int x,int y){//先右再左
if(x==n&&y==m) return true;
for(int i=0;i<2;i++){
node tp;
tp.x=x+dir[i][0];
tp.y=y+dir[i][1];
if(!judge(tp.x,tp.y)) continue;
con[pos(tp.x,tp.y)]=true;
if(dfs(tp.x,tp.y)) return true;
}
return false;
}
int main() {
sdd(n,m);getchar();
int x=n,y=m;
bool flagg=false;//有没有障碍物
rep(i,1,n){
rep(j,1,m){
mp[pos(i,j)]=getchar();
if(mp[pos(i,j)]=='#') flagg=true;
}getchar();
}
if(m==1||n==1){//若只有单行列
printf("%d\n",flagg?0:1);
return 0;
}
int cnt=0;
if(dfs(1,1)){//若能搜到
cnt++;
con[pos(n,m)]=false;
if(dfs(1,1)) cnt++;
}
printf("%d\n",cnt);
return 0;
}
深搜部分也可以完全换成栈模拟深搜
while(!stk.empty()) stk.pop();
node t(1,1);
stk.push(t);
while(!stk.empty()){
t=stk.top();
stk.pop();
con[pos(t.x,t.y)]=true;
if(t.x==n&&t.y==m) break;
for(int i=0;i<2;i++){
node tp;
tp.x=t.x+dir[i][0];
tp.y=t.y+dir[i][1];
if(!judge(tp.x,tp.y)) continue;
stk.push(tp);
}
}
return con[pos(n,m)];