http://acm.hdu.edu.cn/showproblem.php?pid=1045
题意:现在让你在为'.'的位置上放置大炮。
要求:1.同行同列只能有一个大炮;2.若是在同行(同列)有'X',可以将两个大炮隔开的话,那么可以允许同行(同列)有两个(及其以上)大炮出现
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <stdio.h> #include <string.h> #include <string> #include <vector> #include <algorithm> #include <map> #include <queue> #include <stack> #include <math.h> using namespace std; #define INF 0x3f3f3f3f const int maxn = 10; typedef long long LL; char maps[maxn][maxn]; int n, ans; int Judge(int row, int col) { ///判断左边 for(int i=col; i>=0; i--) { if(maps[row][i]=='X') break; if(maps[row][i]=='@') return 0; } ///判断上边 for(int i=row; i>=0; i--) { if(maps[i][col]=='X') break; if(maps[i][col]=='@') return 0; } return 1; } void DFS(int t, int cnt)///t记录当前点,cnt记录当前可以放置大炮的个数 { if(t==n*n) { ans = max(ans, cnt);///ans存最大的放置大炮的个数 return ; } int row=t/n;///行 int col=t%n;///列 if(maps[row][col]=='.' && Judge(row, col))///改点可以放置大炮 { maps[row][col]='@';///将该点置为大炮 DFS(t+1, cnt+1); maps[row][col]='.';///记得回溯时要将位置换回来 } DFS(t+1, cnt);///若不满足放置大炮的要求,则遍历下一点 } int main() { while(scanf("%d", &n), n) { for(int i=0; i<n; i++) scanf("%s", maps[i]); ans = 0; DFS(0, 0); printf("%d ", ans); } return 0; }