题目链接:http://acm.hrbust.edu.cn/vj/index.php?/vj/index.php?c=&c=contest-contest&cid=134#problem/1
大概用二分图缩点建图是比较简单的。深搜也遇见了一些问题。
比如。深搜的临界点我还是要单独判断最后一个点是不是符合条件的。这不科学。
然后。判断当前点所在行和列是不是符合条件的时候。我是只判断了它前面的,大概就是,所有满足条件的几个位置我都是优先放在最前面?但是好像深搜已经把左右的情况都包括了吧。T_T还不太懂。
// dfs + 深搜 #include <stdio.h> #include <string.h> #include <iostream> using namespace std; int n; char mp[10][10]; int ans; bool check(int row, int col) { for (int i=col-1; i>=0; --i) { if (mp[row][i] == 'a') { // 检查该行是否已经有没墙阻隔的大炮。 return false; } else if (mp[row][i] == 'X') break; } for (int i=row-1; i>=0; --i) { if (mp[i][col] == 'a') { // 检查该列是否已经有没有墙阻隔的大炮了。 return false; } else if (mp[i][col] == 'X') { break; } } return true; } void dfs(int con, int tot) { if (con == n*n-1) { if (mp[n-1][n-1] == '.' && check(n-1, n-1)) ans = max(ans, tot); else ans = max(ans, tot-1); return; } int row = con / n; int col = con % n; if (mp[row][col] == '.' && check(row, col)) { // cout << con << "......" << tot << endl; mp[row][col] = 'a'; dfs(con+1, tot+1); mp[row][col] = '.'; } dfs(con+1, tot); } int main() { while(cin >> n) { if (n == 0) break; for (int i=0; i<n; ++i) { for (int j=0; j<n; ++j) { cin >> mp[i][j]; } } ans = 0; dfs(0, 1); // 第一个参数表示当前格子的编号 第二个参数表示当前要安装的大炮编号。 //cout << "===="; cout << ans << endl; } return 0; }