HDU5031


const  int  maxn = 52 ;
int    c[maxn][maxn] ;

struct line{
       int sx , sy , dx , dy , time ;
       line(){}
       line(int sx , int sy , int dx , int dy , int time){
             this->sx = sx ;
             this->sy = sy ;
             this->dx = dx ;
             this->dy = dy ;
             this->time = time ;
       }
       friend bool operator < (const line &a , const line &b){
             return a.time > b.time ;
       }
};

vector<line> g ;

int  n , m , sum , ans  ;

int  can(int x , int y){
     return 0 <= x && x <= n && 0 <= y && y <= m ;
}

int  ok(const line &a){
     for(int x = a.sx , y = a.sy ; can(x , y) ; x += a.dx , y += a.dy){
           if(c[x][y] == 0)  return 0 ;
     }
     return 1 ;
}

int  gao(const line &a){
     for(int x = a.sx , y = a.sy ; can(x , y) ; x += a.dx , y += a.dy){
           sum-- ;
           c[x][y]-- ;
     }
}

int  ungao(const line &a){
     for(int x = a.sx , y = a.sy ; can(x , y) ; x += a.dx , y += a.dy){
           sum++ ;
           c[x][y]++ ;
     }
}

void  dfs(int id , int tsum){
      if(sum == 0){
            ans = min(ans , tsum) ;
            return ;
      }
      int i = id ;
      while(i < g.size() && g[i].time > sum) i++ ;
      if(i == g.size()) return ;

      int s = tsum ;
      s += (sum + g[i].time - 1) / g[i].time ;
      if(s >= ans)  return  ;

      for(; i < g.size() ; i++){
          if(ok(g[i])){
               gao(g[i]) ;
               dfs(i , tsum+1) ;
               ungao(g[i]) ;
          }
      }
}

int  main(){
     int t , i , j , sx , sy , dx , dy , x , y ,  tim , f  ;
     cin>>t ;
     while(t--){
          scanf("%d%d" ,&n , &m) ;
          for(i = 0 ; i <= n ; i++){
              for(j = 0 ; j <= m ; j++) scanf("%d" ,&c[i][j]) ;
          }

          sum = 0 ;
          g.clear() ;

          for(sx = 0 ; sx <= n ; sx++){
              for(sy = 0 ; sy <= m ; sy++){
                   if(c[sx][sy] != 0)  sum += c[sx][sy] ;
                   else  continue ;
                   for(dx = 0 ; dx <= n ; dx++){
                        for(dy = -m ; dy <= m ; dy++){
                            if(__gcd(dx , abs(dy)) != 1) continue ;
                            if(can(sx - dx , sy - dy))  continue ;
                            tim = 0 ;
                            x = sx , y = sy ;
                            f = 1 ;
                            for(; can(x , y) ; x += dx , y += dy){
                                  if(c[x][y] == 0){
                                       f = 0 ;
                                       break ;
                                  }
                                  tim++ ;
                            }
                            if(f && tim >= 3)
                                  g.push_back(line(sx , sy , dx , dy , tim)) ;
                        }
                   }

              }
          }

          sort(g.begin() , g.end()) ;
          ans = 14 ;
          dfs(0 , 0) ;
          cout<< ans << endl ;
     }
     return  0 ;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值