zoukankan      html  css  js  c++  java
  • 堡垒问题

    时限:1000ms 内存限制:10000K  总时限:3000ms

    描述
    城堡是一个4×4的方格,为了保卫城堡,现需要在某些格子里修建一些堡垒。城堡中的某些格子是墙,其余格子都是空格,堡垒只能建在空格里,每个堡垒都可以向上下左右四个方向射击,如果两个堡垒在同一行或同一列,且中间没有墙相隔,则两个堡垒都会把对方打掉。问对于给定的一种状态,最多能够修建几个堡垒。
     
    输入
    每个测例以一个整数n(1<=n<=4)开始,表示城堡的大小。接下来是n行字符每行n个,‘X’表示该位置是墙,‘.’表示该位置是空格。n等于0标志输入结束。
     
    输出
    每个测例在单独的一行输出一个整数:最多修建堡垒的个数。
     
    输入样例
    4
    .X..
    ....
    XX..
    ....
    2
    XX
    .X
    3
    .X.
    X.X
    .X.
    3
    ...
    .XX
    .XX
    4
    ....
    ....
    ....
    ....
    0
     
    输出样例
    5
    1
    5
    2
    4

      

    堡垒问题是在学习递归回溯时的一个经典问题,在递归求解此类问题时,总是先判断当前状态是否行,如果可行,则试着放置一个问题的解,继续递归搜索。递归结束后之后要将状态改变回来,因为前提只是假设先放置着问题的解,之后肯定要修改回来才能保证问题解的正确性。如果忘记修改状态回来,程序肯定会出错。在搜索时,注意条件可以进行剪枝,避免不必要的递归,节约时间。最重要的是要明确递归结束条件。

    /*
    * @author Panoss
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<vector>
    #include<ctime>
    #include<stack>
    #include<queue>
    #include<list>
    using namespace std;
    #define DBG 1
    #define fori(i,a,b) for(int i = (a); i < (b); i++)
    #define forie(i,a,b) for(int i = (a); i <= (b); i++)
    #define ford(i,a,b) for(int i = (a); i > (b); i--)
    #define forde(i,a,b) for(int i = (a); i >= (b); i--)
    #define forls(i,a,b,n) for(int i = (a); i != (b); i = n[i])
    #define mset(a,v) memset(a, v, sizeof(a))
    #define mcpy(a,b) memcpy(a, b, sizeof(a))
    #define dout DBG && cerr << __LINE__ << " >>| "
    #define checkv(x) dout << #x"=" << (x) << " | "<<endl
    #define checka(array,a,b) if(DBG) { \
    dout<<#array"[] | " << endl; \
    forie(i,a,b) cerr <<"["<<i<<"]="<<array[i]<<" |"<<((i-(a)+1)%5?" ":"\n"); \
    if(((b)-(a)+1)%5) cerr<<endl; \
    }
    #define redata(T, x) T x; cin >> x
    #define MIN_LD -2147483648
    #define MAX_LD 2147483647
    #define MIN_LLD -9223372036854775808
    #define MAX_LLD 9223372036854775807
    #define MAX_INF 18446744073709551615
    inline int reint() { int d; scanf("%d",&d); return d; }
    inline long relong() { long l; scanf("%ld",&l); return l; }
    inline char rechar() { scanf(" "); return getchar(); }
    inline double redouble() { double d; scanf("%lf", &d); return d; }
    inline string restring() { string s; cin>>s; return s; }
    
    
    int n,ans;
    char a[4][4];
    
    bool IsCanPlace(int x, int y)
    {
      forde(i,x-1,0)
      {  
        if(a[i][y]=='0') return false;
        if(a[i][y]=='X') break;
      }
      forde(i,y-1,0)
      {
        if(a[x][i]=='0') return false;
        if(a[x][i]=='X') break;
      }
      return true;
    }
    void DFS(int k, int current_ans)
    {
      if(k==n*n)
      {
        ans = max(ans,current_ans);
        return ;
      }
      else
      {
        int x = k/n;
        int y = k%n;
        if(a[x][y]=='.'&&IsCanPlace(x,y))
        {
          a[x][y] ='0'; ///先放一个堡垒
          DFS(k+1,current_ans+1);
          a[x][y] ='.'; ///搜索结束后再放置回来
        }
        DFS(k+1,current_ans);///搜索不放的状态
      }
    }
    int main()
    {
      while(scanf("%d",&n)==1&&n)
      {
        fori(i,0,n)
        scanf("%s",a[i]);
        ans=0;
        DFS(0,0);
        cout<<ans<<endl;
      }
      return 0;
    }
  • 相关阅读:
    Android游戏开发22:Android动画的实现J2me游戏类库用于Android开发
    android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精通SQLITE (第三部分,完整代码)
    使用OGR创建dxf格式矢量数据
    mysql 数据库引擎 MyISAM InnoDB 大比拼 区别
    android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精通SQLITE (第二部分)
    mysql 更改数据库引擎
    android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精通SQLITE (第一部分)
    android 数字键盘使用
    MySQL Innodb数据库性能实践
    eclipse : Error while performing database login with the driver null
  • 原文地址:https://www.cnblogs.com/Panoss/p/3740088.html
Copyright © 2011-2022 走看看