一、问题描述
题目地址<ZOJ 1002>:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1002
n*n的地图,'.'表示空地,'X'表示墙,现在往地图上放置炮塔,要求两两炮塔不能同行同列(除非之间有墙),给定一种地图,问这个地图最多可以放置多少个炮塔?
二、与八皇后问题进行比较
与八皇后不同的时,八皇后问题每行放一个皇后,且最多放一个。而该问题,每行可以放多个炮塔,取决于墙的位置。
不过,除了上面的不同点之外,这个问题与八皇后十分像。
八皇后问题中,我采用逐行扫描,逐行考虑皇后的放置。在这个问题中,我们可以按照每个位置扫描,每个位置来考虑炮塔放置的问题。另外,也只是判定能不能放置的条件有所改变。
三、程序实现
下面是我的AC代码
1 #include<iostream> 2 using namespace std; 3 4 char **s; //存储地图 5 int n ; //边长 6 int m ; 7 int mm; 8 9 //判断能不能放 10 int canPut(int i , int j) 11 { 12 int ok = 1; 13 if(s[i][j] == '1') ok = 0; 14 for(int k = i;k >= 0;k--) 15 { 16 if(s[k][j] == 'X') break; 17 if(s[k][j] == '1') ok = 0; 18 } 19 20 for(int k = i;k < n;k++) 21 { 22 if(s[k][j] == 'X') break; 23 if(s[k][j] == '1') ok = 0; 24 } 25 26 for(int k = j;k >= 0;k--) 27 { 28 if(s[i][k] == 'X') break; 29 if(s[i][k] == '1') ok = 0; 30 } 31 32 for(int k = j;k < n;k++) 33 { 34 if(s[i][k] == 'X') break; 35 if(s[i][k] == '1') ok = 0; 36 } 37 return ok; 38 } 39 40 //搜索 41 void backTrack(int h) 42 { 43 for(int i = h;i < n;i++) 44 for(int j = 0;j < n;j++) 45 { 46 if(s[i][j]!='X' && canPut(i,j)) 47 { 48 s[i][j] = '1'; 49 m++; 50 backTrack(i); 51 if(m > mm) mm = m; 52 s[i][j] = '.'; 53 m--; 54 } 55 } 56 } 57 58 int main() 59 { 60 n = 0; 61 while(cin >> n) 62 { 63 if(n != 0) 64 { 65 s = new char*[n]; 66 for(int i = 0;i < n;i++) 67 { 68 s[i] = new char[n]; 69 } 70 71 for(int i = 0;i < n;i++) 72 for(int j = 0;j < n;j++) 73 cin >> s[i][j]; 74 75 backTrack(0); 76 cout << mm<<endl; 77 mm = 0; 78 m = 0; 79 } 80 } 81 return 0; 82 }
四、感想
自己通过自己独立分析问题,自己独立编程实现,最后这个题目顺利AC,这个节奏还是很好的~
另外,感觉这个问题真的和八皇后很像。
最后,YZY,我想你!~
浙公网安备 33010602011771号