HDU 1045 Fire Net

 这是一道N皇后问题的小变种。我在编写的过程中开始遇到的困难:由于地图上可能有墙(‘X’),所以每一行和每一列不一定只能放一个机关枪,问题出来了,N后问题是每搜索一行都要去搜索下一行,但是这道题目不能这么做,因为这一行可能还能继续放。所以,递归函数的参数应该有2个------一个记录行下标,一个记录列下标。因此,搜索行需要递归,搜索列同样也要递归。

行的递归:for(j=m; j<=n; j++)
 {
  if(map[x][j]=='.' && satisfied(x, j))
  {
   map[x][j] = 'E';
   max_sum++;
   DFS(x,j+1);//这就是行的递归
   map[x][j] = '.';
   max_sum--;
  } 
 }

当然,行递归完之后就是列的递归了:DFS(x+1,1);

同时,航宇列递归完了都要有其相应的出口:

if(x>n)  行递归出口
 {
  if(sum<=max_sum)
   sum = max_sum;
  return ;
 }
 if(m>n)   列递归出口
 {
  if(sum<=max_sum)
   sum = max_sum;
  DFS(x+1,1);
  return ;
 }

 

 

AC源代码:

#include <iostream>
using namespace std;
char map[5][5];
int n, max_sum, sum;

bool satisfied(int x, int y)
{
 int i, j;
 bool flagRowLeft ,flagRowRight ,flagLineUp,flagLineDown;
 flagRowLeft = flagRowRight = flagLineUp= flagLineDown =false;
 for(j=y; j>=1; j--)
 {
  if(map[x][j]=='E')
  {
   flagRowLeft = false;
   break;
  }
  if(map[x][j]=='X')
  {
   flagRowLeft = true;
   break;
  }
 }
 if(j==0)
  flagRowLeft = true;
 for(j=y; j<=n; j++)
 {
  if(map[x][j]=='E')
  {
   flagRowRight = false;
   break;
  }
  if(map[x][j]=='X')
  {
   flagRowRight = true;
   break;
  }
 }
 if(j==n+1)
  flagRowRight = true;

 for(i=x; i>=1; i--)
 {
  if(map[i][y]=='E')
  {
   flagLineUp = false;
   break;
  }
  if(map[i][y]=='X')
  {
   flagLineUp = true;
   break;
  }
 }
 if(i==0)
  flagLineUp = true;
 for(i=x; i<=n; i++)
 {
  if(map[i][y]=='E')
  {
   flagLineDown = false;
   break;
  }
  if(map[i][y]=='X')
  {
   flagLineDown = true;
   break;
  }
 }
 if(i==n+1)
  flagLineDown = true;

 if(flagRowLeft && flagRowRight && flagLineUp && flagLineDown)
  return true;
 return false;
}


void DFS(int x, int m)
{
 int i, j, k;
 if(x>n)
 {
  if(sum<=max_sum)
   sum = max_sum;
  return ;
 }
 if(m>n)
 {
  if(sum<=max_sum)
   sum = max_sum;
  DFS(x+1,1);
  return ;
 }
 for(j=m; j<=n; j++)
 {
  if(map[x][j]=='.' && satisfied(x, j))
  {
   map[x][j] = 'E';
   max_sum++;
   DFS(x,j+1);
   map[x][j] = '.';
   max_sum--;
  } 
 }
 DFS(x+1,1);
 
}

void main()
{
 int i, j;
 while(cin>>n&& n)
 {
  max_sum = 0;
  sum=0;
  for(i=1; i<=n; i++)
   for(j=1; j<=n; j++)
    cin>>map[i][j];
  DFS(1, 1);
  cout<<sum<<endl;
 }
}

 

微笑
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值