1 题意:给出一张地图, 'X'是墙,'.'是可放的位置,求棋盘上最多放多少个车(中国象棋)。
2 分析:回溯
注意:在进入下一层的判断,如果符合某个约束条件,则进入下一层第一个递归实例,不符合或者退出一第一个递归实例后,都应该进入第二个递归实例,不然怎么回溯;另外注意不要忘记在最后一层的递归中,return。
3
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
char mat[5][5];
int best;
int kk;
bool Judge(int cur){
int dxup,dxdown;
dxup=dxdown=cur/kk;
int dyleft,dyright;
dyleft=dyright=cur%kk;
int step=20;
while(step--){
if(dxup>0){
dxup--;
if(mat[dxup][cur%kk]=='X'){
dxup=0;
}
else if(mat[dxup][cur%kk]=='Q'){
return false;
}
}
if(dxdown<kk-1){
dxdown++;
if(mat[dxdown][cur%kk]=='X'){
dxdown=kk-1;
}
else if(mat[dxdown][cur%kk]=='Q'){
return false;
}
}
if(dyleft>0){
dyleft--;
if(mat[cur/kk][dyleft]=='X'){
dyleft=0;
}
else if(mat[cur/kk][dyleft]=='Q'){
return false;
}
}
if(dyright<kk-1){
dyright++;
if(mat[cur/kk][dyright]=='X'){
dyright=kk-1;
}
else if(mat[cur/kk][dyright]=='Q'){
return false;
}
}
if(dxup==0&&dyleft==0&&dxdown==kk-1&&dyright==kk-1){
return true;
}
}
return true;
}
void Go(int cur,int sum){
if(cur==kk*kk){
best=max(sum,best);
return ;//不要忘记退出 ①
}
if(mat[cur/kk][cur%kk]=='.'&&Judge(cur)){
mat[cur/kk][cur%kk]='Q';
Go(cur+1,sum+1);
mat[cur/kk][cur%kk]='.';
}
//else{ ② 不能加else,否则第一个条件中的递归退出后无法进入这一个。
Go(cur+1,sum);
//}
}
int main()
{
while(~scanf("%d",&kk)&&kk){
for(int i=0;i<kk;i++){
scanf("%s",mat[i]);
}
best=0;
Go(0,0);
cout<<best<<endl;
}
return 0;
}