题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1002
题目大意:
给你一个n*n的地图,地图上的空白部分可以放棋子,也有墙,问最多能放多少棋子使得棋子两两不会袭击?
棋子袭击当且仅当处在同一行或者同一列上并且中间没有墙的阻隔。
真是好久没写过搜索题了。。这道题都写了这么久!!
直接写dfs(x,y,now) 代表我现在站在x点,y点上,那么就只能产生两种状态,放棋子或者不放棋子。
然后写一个C(x,y)代表当前点能否放置棋子。
什么情况下可以放置棋子呢?
因为我们是从左上角到右下角放的嘛,所以说只需要看左边和上边有没有棋子了。
代码:
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <vector>
#include <map>
#include <set>
#include <iterator>
#include <functional>
#include <cmath>
#include <numeric>
using namespace std; typedef long long LL; int n;
char mp[][];
int maxn = ; bool C(int x,int y){
bool hang = true,lie = true;
for(int i=x-;i>=;i--){
if( mp[i][y]=='@' ) {
hang = false;
break;
}
if( mp[i][y]=='X' ){
hang = true;
break;
}
}
for(int j=y-;j>=;j--){
if( mp[x][j]=='@' ) {
lie = false;
break;
}
if( mp[x][j]=='X' ){
lie = true;
break;
}
}
return hang&&lie;
} void dfs(int x,int y,int now){
// printf("x=%d y=%d now=%d\n",x,y,now);
if( x==n&&y==n ){
if( mp[x][y]=='.' && C(x,y) ) now = now+;
maxn = max(maxn,now);
return;
}
if( mp[x][y]=='.' && C(x,y) ){
mp[x][y] = '@';
if(y+<=n) dfs(x,y+,now+);
else if(x+<=n) dfs(x+,,now+);
mp[x][y] = '.';
}
if(y+<=n) dfs(x,y+,now);
else if(x+<=n) dfs(x+,,now);
} int main(){
// freopen("output.txt","w",stdout);
while(scanf("%d",&n)!=EOF&&n){
if( n== ) break;
maxn = ;
for(int i=;i<=n;i++){
scanf("%s",mp[i]+);
}
dfs(,,);
printf("%d\n",maxn);
}
return ;
}