ZOJ1002 Fire Net(DFS)

Problem Description
Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street or a piece of wall. 


A blockhouse is a small castle that has four openings through which to shoot. The four openings are facing North, East, South, and West, respectively. There will be one machine gun shooting through each opening. 


Here we assume that a bullet is so powerful that it can run across any distance and destroy a blockhouse on its way. On the other hand, a wall is so strongly built that can stop the bullets. 


The goal is to place as many blockhouses in a city as possible so that no two can destroy each other. A configuration of blockhouses is legal provided that no two blockhouses are on the same horizontal row or vertical column in a map unless there is at least one wall separating them. In this problem we will consider small square cities (at most 4x4) that contain walls through which bullets cannot run through. 


The following image shows five pictures of the same board. The first picture is the empty board, the second and third pictures show legal configurations, and the fourth and fifth pictures show illegal configurations. For this board, the maximum number of blockhouses in a legal configuration is 5; the second picture shows one way to do it, but there are several other ways. 






Your task is to write a program that, given a description of a map, calculates the maximum number of blockhouses that can be placed in the city in a legal configuration. 
 


Input
The input file contains one or more map descriptions, followed by a line containing the number 0 that signals the end of the file. Each map description begins with a line containing a positive integer n that is the size of the city; n will be at most 4. The next n lines each describe one row of the map, with a '.' indicating an open space and an uppercase 'X' indicating a wall. There are no spaces in the input file.
 


Output
For each test case, output one line containing the maximum number of blockhouses that can be placed in the city in a legal configuration.
 


Sample Input
4
.X..
....
XX..
....
2
XX
.X
3
.X.
X.X
.X.
3
...
.XX
.XX
4
....
....
....
....
0
 


Sample Output
5
1
5
2
4
 

问题描述

假设我们有一个有着笔直街道的广场城市。城市地图是一个正方形的板,有n行和n列,分别代表一条街道或一块墙。
“是一个小城堡,有四个孔,其中拍摄。四个空缺分别面向北部、East、南部和欧美地区。每一个开口都会有一个机枪射击。
在这里,我们假定子弹是如此强大,它可以运行在任何距离和毁灭的道路上的碉堡。另一方面,一堵墙非常坚固,可以阻挡子弹。
其目标是把城市中的许多碉堡使没有两可以摧毁对方。配置碉堡是法律规定,没有两个碉堡在地图中的同一行或垂直柱除非至少有一个壁分离。在这个问题上我们会考虑小城市广场(最多4x4)包含通过子弹不能穿过墙壁。
下图显示同一块板上的五张图片。第一张图片是空板,第二张和第三张图片显示了合法的配置,第四和第五张图片显示了非法配置。这一局,在法律结构的碉堡数目最多为5;第二张图片展示了一种方式,但也有一些其他的方法。
你的任务是写一个程序,设计一个地图,计算出碉堡可以放置在该市的法律配置的最大数量。
输入
输入文件包含一个或多个map描述,后面是一条包含数字0的行,该行指示文件的结尾。每一个地图描述都以一个正整数n作为城市的大小开始,n最多为4。接下来的n行分别描述了一行图,其中一个“A”表示一个开放的空间和大写的“X”表示一个墙。输入文件中没有空格。
输出

对于每一个测试案例,输出一行包含碉堡可以放置在该市的法律配置的最大数量。


思路:

1.与八皇后问题类似

2.回溯算法

1)若能放碉堡,变量加1;递归完毕时,单元格恢复,以计算下一方案

2)若不放,则递归


//将表格从0开始编号,即从0-15. 由于我们需要对每个单元格都进行一个判断,所以我们采用k编号的方式而不是坐标的方式   
#include  
using namespace std;  
char map[100][100];  
int ans=0,n;  
int c_put(int x,int y)  
{  
    //判断行上是否合法   
    for(int i=x-1;i>=0;i--)  
    {  
        if(map[i][y]=='O')//如果此行上面有碉堡就返回   
            return 0;  
        if(map[i][y]=='X')//如果在遇到碉堡之前先有了一道墙则继续,可以放置  
            break;   
    }  
    //判断在列上的合法性  
    for(int i=y-1;i>=0;i--)  
    {  
        if(map[x][i]=='O')//如果此列上面有碉堡就返回   
            return 0;  
        if(map[x][i]=='X')//如果在遇到碉堡之前先有了一道墙则继续,可以放置  
            break;   
    }  
    return 1;     
}   
void dfs(int k,int num)//当前的单元格的编号是k,当前情况下num为最大的碉堡数   
{  
    int x,y;   
    if(k==n*n)//遍历到最后一个单元格的下一个,说明之前所有的单元格都被遍历了   
    {  
        if(num>ans)  
            ans=num;  
        return ;  
    }  
    else  
    {  
        x=k/n;  
        y=k%n;  
        //如本单元格可以放置碉堡,采取:   
        if(map[x][y]=='.'&&c_put(x,y))//当前位置是空地并且可以放置碉堡,不会产生冲突   
        {  
            map[x][y]='O';//放置碉堡  
            dfs(k+1,num+1);   
            map[x][y]='.';//恢复原始设置   
        }   
        //如本单元格不可以放置碉堡,采取:  
        dfs(k+1,num);  
    }   
      
}  
int main()  
{  
    while(cin>>n&&n)  
    {  
        for(int i=0;i>map[i][j];  
        dfs(0,0);  
        cout<

#include
//城市的尺寸
int n;
//城市的地图,最多是4*4
char map[4][4];
//最多放的炮塔数
int bestn;
//看炮塔是否能够放置
int canput(int row,int col)
{
  int i;
  for(i=row-1;i>=0;i--)
  {
     if(map[i][col]=='X')
     {
         break;
     }
     if(map[i][col]=='o')
     {
         return 0;
     }
  }
  for(i=col-1;i>=0;i--)
  {
     if(map[row][i]=='X')
     {
        break;
     }
     if(map[row][i]=='o')
     {
        return 0;
     }
  }
  return 1;
}
//K表示放置炮塔的位置
void backtrack(int k,int current)
{
   int x,y;
   if(k>=n*n)
   {
       if(current>bestn)
       {
           bestn=current;
       }
       return;
   }
   else
   {
     x=k/n;
     y=k%n;
     if(map[x][y]=='.'&&canput(x,y))
     {
        map[x][y]='o';
        backtrack(k+1,current+1);
        map[x][y]='.';
     }
     backtrack(k+1,current);
   }
}
void initial()
{
  int i,j;
  for(i=0;i<4;i++)
  {
      for(j=0;j<4;j++)
      {
          map[i][j]='.';
      }
  }
}
int main()
{
    scanf("%d",&n);
    while(n)
    {
       int i,j;
       bestn=0;
       initial();
       for(i=0;i


你可能感兴趣的:(DFS)