zoj1002

小灰灰 2023-03-14 05:53 34阅读 0赞

题目传送门
题目大意:
在一个最大为4*4的方格内建blockhouse(
碉堡)
但是有条件

  1. 两个及以上blockhouse不能位于同一行或者同一列
  2. 如果有wall,两个blockhouse可以位于其两侧
  3. blockhouse只能建在空地
    注意的点
  4. 多次输入;输入0时,结束
    解题思路:
    方格最大是4*4,那么我们就简单点,使用暴力的方法,枚举也行,深搜也行,其实两者差不多。最大枚举次数为216,即每个格子都有两种可能,放和不放。深搜的时候要记得回溯。枚举的话,就可以写16重循环,每重循环设放和不放。
    优化:其实我们没必要进行16重循环,我们用一个状态数组记录点为“。”的坐标,再看看总坐标数为多少,就可以确定枚举的次数了。

    include

    using namespace std;
    int n,ans,count;
    char s[5][5];
    struct node
    {

    1. int x,y;

    } v[20];
    bool judge(int row,int col)//判断插入一个炮垒是否合法
    {

    1. int i,j,flag1=1,flag2=1;
    2. for(i=1;i<col;i++)//在行判断
    3. {
    4. if(s[row][i]=='a')
    5. flag1=0;
    6. if(s[row][i]=='X')
    7. flag1=1;
    8. }
    9. for(i=1;i<row;i++)//在列判断
    10. {
    11. if(s[i][col]=='a')
    12. flag2=0;
    13. if(s[i][col]=='X')
    14. flag2=1;
    15. }
    16. if(flag1&&flag2)
    17. return true;
    18. return false;

    }
    void dfs(int num,int cur)//状态数组当前编号,当前放置碉堡数
    {

    1. int dx=v[num].x;
    2. int dy=v[num].y;
    3. if(num==count)
    4. {
    5. ans=max(ans,cur);
    6. return ;
    7. }
    8. int i,j;
    9. for(i=1;i<=2;i++)
    10. {
    11. if(i==1&&judge(dx,dy))//表示放置碉堡
    12. {
    13. s[dx][dy]='a';//a表示放置碉堡
    14. dfs(num+1,cur+1);
    15. }
    16. else if(i==2)//不放置碉堡
    17. {
    18. s[dx][dy]='.';//回溯
    19. dfs(num+1,cur);
    20. }
    21. }

    }
    int main()
    {

    1. int i,j;
    2. while(cin>>n&&n)
    3. {
    4. count=0;//复位
    5. ans=0;//复位
    6. for(i=1;i<=n;i++)
    7. for(j=1;j<=n;j++)
    8. {
    9. cin>>s[i][j];
    10. if(s[i][j]=='.')
    11. v[count++]={ i,j};
    12. }
    13. dfs(0,0);
    14. cout<<ans<<endl;
    15. }

    }

发表评论

表情:
评论列表 (有 0 条评论,34人围观)

还没有评论,来说两句吧...

相关阅读

    相关 zoj1002

    [题目传送门][Link 1] 题目大意: 在一个最大为4\4的方格内建blockhouse( 碉堡) 但是有条件 1. 两个及以上blockhouse不能

    相关 (回溯)ZOJ1002 Fire Net

    传送门: [ZOJ1002 Fire Net][] 哈哈哈,其实这道题目只是八皇后题目的简单变形,一开始,感觉自己做不上来,就直接搜答案。看了几个题解,感觉写得很复杂,也不想