回溯法

http://acm.hdu.edu.cn/showproblem.php?pid=1045


在最多为 4 * 4 的方阵中,圆形代表堡垒,正方形代表墙,堡垒射出的子弹无法穿过墙,求任何两个堡垒都不能射中对方的最大的堡垒放置数?

#pragma warning (disable:4786)  
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
string map[6];
int arr[20];                        //总元素数组
int used_row[6],used_column[6];     //标记行和列是否已被使用
int n;                              //行(列)数
int DFS( int index ){
	if( index == n * n )
		return 0;

	//根据元素的坐标计算其所在行列数
	int row = index / n;
	int column = index % n;

	//如果是墙,将其所在的行和列设置为未使用
    if( arr[ index ] == 1 ){
		used_row[row] = 0;
		used_column[column] = 0;
		return DFS( index + 1 );
	}

	//对两种情况进行回溯,一种是在该处放置堡垒,另一种是不放置
	int re1 = DFS(  index + 1 );
	int re2 = 0;
	
	if( used_row[row] == 0 && used_column[column] == 0 ){
		used_row[row] = 1;
		used_column[column] = 1;
		re2 = DFS( index +1 ) + 1; 

		//不要忘了恢复状态
		used_row[row] = 0;
		used_column[column] = 0;		
	}
	
	//返回放置和不放置堡垒两种情况中得到较好结果的那种
	if( re2 < re1 )		
		return re1;
	else return re2;

}
			
int main(){
    int i,j;
    while( scanf( "%d", &n ) &&  n ){
        memset( used_row, 0, sizeof( used_row ) );
        memset( used_column, 0, sizeof( used_column ) );
		memset( arr, 0, sizeof(arr) );
        string s;
        for( i = 0; i < n; i ++ ){            
            cin>>map[i];
            for( j = 0; j < n; j ++ ){                
                if( map[i][j] == 'X' )
                    arr[i * n + j] = 1;
            }
        }
        printf( "%d\n", DFS( 0 ) );
    }
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值