题意:一些机枪彼此不能在同一行和同一列,但是由于有墙的阻隔,能保证子弹无法穿透,即可以同行同列,现问如果说给了一个n*n(n<=4)的矩阵,并给出了墙的分布情况,能否求出最大能繁殖的机枪数。
思路:之前按八皇后的思想一行一行搜,不理想,之后改成一个格一个格的搜,回溯要理解好就没问题。
#include <iostream> #include <cstdio> using namespace std; int n,best; char map[4][4]; int canput(int row,int col) { int i; for(i=row-1;i>=0;i--) //如果(row,col)左面的先是遇到墙,则可行 { if(map[i][col]==‘X‘) { break; } if(map[i][col]==‘Y‘)//如果(row,col)左面的先是遇到机枪,则跪 { return 0; } } for(i=col-1;i>=0;i--) //如果(row,col)上面的先是遇到墙,则可行 { if(map[row][i]==‘X‘) { break; } if(map[row][i]==‘Y‘)//如果(row,col)上面的先是遇到机枪,则跪 { return 0; } } return 1; } void backtrack(int k,int cur)//K表示放置炮塔的位置(1~16),cur表示当前放置的总数 { int x,y; if(k==n*n) { if(cur>best) { best=cur; } return; } else { x=k/n; y=k%n; if(map[x][y]==‘.‘&& canput(x,y)) { map[x][y]=‘Y‘; backtrack(k+1,cur+1); //加入此机枪点,深度dfs map[x][y]=‘.‘; //不加入此机枪点,回溯 } backtrack(k+1,cur);//(x,y)能加入机枪却不加 和 不能加入机枪的两种情况统一在此处理 //即处理下一个点而认为不加入 } } int main() { // freopen("in.txt","r",stdin); while(cin >> n && n != 0) { best=0; for(int i=0;i { for(int j=0;j { char ch=getchar(); if(ch==‘\n‘) //为了吸收每个句尾的回车 { j--; continue; } else map[i][j]=ch; } } backtrack(0,0); printf("%d\n",best); } return 0; }
时间: 2024-10-13 01:36:59