算法——堡垒问题

城堡是一个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");
}

点赞