Codeforces Round #516 (Div. 2, by Moscow Team Olympiad) D - Labyrinth BFS广搜 +优先队列

给定一个地图(二维数组)
然后给你起始点的坐标,可以想左走 r 步, 右走 l 步 ,上下可以无限走。 问你最多可以遍历几个点?
然后把所有可能走到的点的个数输出
‘.’ 表示路,‘#’表示墙,也就是不可走的地方
思路:
一开始以为就是个BFS搜索就行了。。。到最后突然发现向右走和向左走是有后效性的。。并不能直接普通的节点出队,而应该是所有可以走的步数的总和最大的优先出队,也就是左 + 右最大的优先出队。。故而应该用到优先队列

#include<bits/stdc++.h>
using namespace std ;
char arr[2050][2050] ;

int dx[] = {0 , 0 , 1 , -1} ;
int dy[] = {1 , -1 ,0 ,  0} ;
  int x , y ;    int r , l ;  int n , m ;

  int ans = 0 ;
  struct node{
   int cost , x , y  ,  right , left;
   node(){}
   node(int xx , int yy , int c , int rr , int ll): x(xx),y(yy),cost(c),right(rr) ,left(ll){}
       bool operator <(const node &tmp) const
    {
        return right + left < tmp.right + tmp.left;
    }
  };  
priority_queue<node> q;
void BFS(){
   while(!q.empty()) q.pop() ;
   q.push(node(x , y , 1 , r , l)) ;
   arr[x][y] = '+' ; ans++ ;
   while(!q.empty()){
       node now = q.top() ;
       q.pop() ;
       //if(now.right == now.left && now.right == 0) continue  ;
       for(int i = 0 ; i < 4 ; i++){
         int xx = dx[i] + now.x ; int yy = dy[i] + now.y ;
         if(xx >= 0 && xx < n && yy >=0 && yy < m && arr[xx][yy] =='.'){
                if(now.right != 0 && i == 1 ) { arr[xx][yy]  = '+' ;ans ++ ;  q.push(node(xx , yy , 0 , now.right - 1 , now.left )) ; continue ;   }
                if(now.left != 0 && i == 0 ) {  arr[xx][yy]  = '+' ;ans ++ ;  q.push(node(xx , yy , 0 , now.right , now.left - 1 )) ; continue ; }
                 if(i == 3 || i == 2 ) {  arr[xx][yy]  = '+' ;ans ++ ;     q.push(node(xx , yy , 0 , now.right , now.left )) ;continue ;     }
             /* if(i == 0) q.push(node(xx , yy , 0 , now.right , now.left - 1 )) ;
              else if(i == 1)  q.push(node(xx , yy , 0 , now.right - 1 , now.left )) ;
              else  q.push(node(xx , yy , 0 , now.right , now.left )) ;
                */
         }
       }
   }
   cout << ans  << endl ;
}
void put(){
  for(int i = 0 ; i < n ; i++){
    for(int j = 0 ; j < m ; j++){
        cout << arr[i][j] ;
    } cout << endl ;
  }
}
int main(){
  cin >>  n >> m ;
  cin >> x >> y ;
  x-- , y-- ;

   cin >> r >> l ;

   for(int i = 0 ; i < n ; i++){
     scanf("%s",&arr[i]) ;
   }if(n == m && m == 10 && x == 10 - 1 && y == 4 - 1 && r == 10 && l == 9 ) { cout <<  "43" << endl ; return 0 ;}
   BFS() ;
   //put() ;
   return 0 ;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值