HDU 4101 有意思的广搜

来源:互联网 发布:输出数组元素 15 分 编辑:程序博客网 时间:2024/06/12 06:25

题意:在一个n*n的矩阵内,两个人想要找到一个 “ 宝藏 “,用-1表示。其中有空地,每回合可任意穿梭,用0表示,有怪物,无法直接穿过,需要杀死,每回合砍1 HP,等于0时死亡,由两人从最外围开始,每人一回合行动,问谁能获得 ”  宝藏  “ 。

题解: 看似博弈 ,同样可以从必胜状态考虑,当宝藏周围只剩下最后一圈血量为1的怪物时,  谁先打死那个怪物,谁就输了。

             两人都不愿意杀死那只堵着宝藏门的第一只怪 ,所以两人的状态就是一直在砍门外面的怪,你一刀我一刀。所以我们只需要知道除了最后一圈怪,门外的怪物血量之和为奇数还是偶数就可以判断是先者还是后者赢。

             先从起点开始广搜,找到那最内围的一圈怪物,将其标记为1

             再从外围开始搜,搜到外围怪物,num += 怪物血量。  搜到内围怪我  num += (怪物血量 - 1),留一个怪看门

代码 :

#include<stdio.h>
#include<iostream>
#include<queue>
using namespace std;
int mark_bfs[333][333], mark_bfs2[333][333], map[333][333], flag, num, n, m; 
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
struct Node
{
   int x, y;       
}st;
void bfs(Node st)
{
    queue<Node> p;
    p.push(st);
    mark_bfs[st.x][st.y] = 1;
    Node v, vn; 
    while(!p.empty())
    {
      vn = p.front();
      p.pop();
      for(int i =0; i < 4; i++)
      {
        v.x = vn.x + dx[i];
        v.y = vn.y + dy[i];  
       
        if((v.x == n - 1 || v.x == 0 || v.y == m - 1 || v.y == 0)&&(map[v.x][v.y] == 0)) { flag = 1; return; }
        if(mark_bfs[v.x][v.y])  continue; 
        if(map[v.x][v.y] == 0)  
          p.push(v); 
        mark_bfs[v.x][v.y] = 1;
                     
      }                  
    }      

void bfs2(Node st)
{
    queue<Node> p;
    p.push(st);
    if(mark_bfs2[st.x][st.y])   return;
    mark_bfs2[st.x][st.y] = 1;
    Node v, vn;
    while(!p.empty())
    {
       vn = p.front();
       p.pop(); 
       num += map[vn.x][vn.y]; 
       for(int i = 0 ;i < 4; i++)
       {
         v.x = vn.x + dx[i];
         v.y = vn.y + dy[i];
         if(v.x >= n || v.x < 0 || v.y >= m || v.y < 0)  continue;      
         if(mark_bfs2[v.x][v.y])  continue;
         if(mark_bfs[v.x][v.y])   {    num += (map[v.x][v.y] - 1);  mark_bfs2[v.x][v.y] = 1; continue; }




         mark_bfs2[v.x][v.y] = 1;
         p.push(v); 
       }           
         
    }     
}
int main()
{
  while(scanf("%d%d", &n, &m)!=EOF)
  {
      memset(mark_bfs, 0, sizeof(mark_bfs));
      memset(mark_bfs2, 0, sizeof(mark_bfs2));
      for(int i = 0; i < n; i ++)
      {
        for(int j = 0; j < m; j ++)
        {
          scanf("%d", &map[i][j]);
          if(map[i][j] == -1)
          {
            st.x = i;
            st.y = j;             
          }        
        }        
      } 
      flag = 0;
      num = 0;
      bfs(st); 
      if(flag)  { printf("Ali Win\n"); continue;} 
      for(int i = 0; i < m; i++)
      {
           st.x = 0;
           st.y = i;
           bfs2(st); 
           st.x = n - 1;
           st.y = i;
           bfs2(st);        
      }               
      for(int i = 0; i < n; i++)
      {
           st.x = i;
           st.y = 0;
           bfs2(st);
           st.x = i;
           st.y = m - 1;
           bfs2(st);        
      }  
      if(num % 2) printf("Ali Win\n");
      else printf("Baba Win\n");
  }    

0 0