首页 > 代码库 > 【搜索 回溯】 zoj 1002

【搜索 回溯】 zoj 1002

题意:一些机枪彼此不能在同一行和同一列,但是由于有墙的阻隔,能保证子弹无法穿透,即可以同行同列,现问如果说给了一个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;}

 

【搜索 回溯】 zoj 1002