城堡是一个4×4的方格,为了保卫城堡,现需要在某些格子里修建一些堡垒。城堡中的某些格子是墙,其余格子都是空格,堡垒只能建在空格里,每个堡垒都可以向上下左右四个方向射击,如果两个堡垒在同一行或同一列,且中间没有墙相隔,则两个堡垒都会把对方打掉。问对于给定的一种状态,最多能够修建几个堡垒。
使用回溯算法解决
#include<fstream>
#include <iostream>
using namespace std;
int Arr[4][4] = { 0 };
int n = 4,max = 0;
void readdata(){
fstream f("d:\\1.txt");
int a = -1;
for (int i = 0; i < 4; i++){
for (int j = 0; j < 4; j++){
f >> a;
Arr[i][j] = a;
}
}
}
void checkmax(){
int sum = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j<n; j++)
if (Arr[i][j] == 2)
sum++;
if (sum>max)//取置堡垒个数最多的
max = sum;
}
/************************************************************************/
/* 判断是否可以放城堡,m每次递增1,假设判断arr[row][col]位置是否可以放,分析知row的下面必然没有城堡,col的右边必然没有城堡
故只需要判断row的上边和col的左边是有堡垒即可
*/
/************************************************************************/
bool canplace(int m){
int row, col;
row = m / n;
col = m%n;
int c = col;
if (Arr[row][col] == 1)
return false;
//判断col的左边是否有堡垒
while (col >= 0 && Arr[row][col] == 0)
col--;
if (col < 0 || (col >= 0 && Arr[row][col] == 1))
{//判断row的上边是否有堡垒
while (row >= 0 && Arr[row][c] == 0)
row--;
if (row < 0 || (row >= 0 && Arr[row][c] == 1))
return true;
}
return false;
}
void search(int m)
{
int row, col;
row = m / n;
col = m % n;
if (m == n*n)
checkmax();
else
{
search(m + 1);//不放堡垒
if (canplace(m))//满足将Arr[row][col]置为堡垒的条件
{
Arr[row][col] = 2;//将Arr[m/n][col]置为堡垒
search(m + 1);
Arr[row][col] = 0;//移除
}
}
}
void main()
{
readdata();
search(0);
cout << max << endl;
system("pause");
}