海贼007

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

算法思考过程:

1.goose周围一定距离内必定是goose,根据这个条件,整个图可以分成很多独立的区域。

2.每个区域内可以是goose或duck,互不影响。但是根据题目要求,须保证至少有一个区域是goose。

3.找出区域数n,最后可能的情况是(2^n-1)%1000000007。

4.时间复杂度:算法实现出来用了4重循环,时间复杂度为O(n^4)。但是这四重循环内的操作主要是为了去标志set,而set的大小为n^2,且每个元素只被标记一次,即实际的时间复杂度应该是O(n^2)。

菜鸟改了好几次后的代码:

import java.util.*;
import java.util.regex.*;
import java.text.*;
import java.math.*;


public class GooseInZooDivTwo
{
    private int lenx,leny;
    public int count(String[] field, int dist)
    {
        boolean[][] set = new boolean[50][50];
        int i,j,count;
        
        lenx=field.length;
        leny=field[0].length();
        
        count=0;
        for(i=0;i<lenx;i++){
            for(j=0;j<leny;j++){
                if(field[i].charAt(j)=='v'&&!set[i][j]){
                    update(set,i,j,field,dist);
                    count++;
                }
            }
        }
        int r=1;
        for(i=0;i<count;i++){
            r=(r*2)%1000000007;
        }
        return r-1;
    }
    
    private void update(boolean[][] set,int point_x,int point_y,String[] field,int dist){
        int i,j;
        
        set[point_x][point_y]=true;
        for(i=0;i<lenx;i++){
            for(j=0;j<leny;j++){
                if(field[i].charAt(j)=='v'&&Math.abs(i-point_x)+Math.abs(j-point_y)<=dist&&!set[i][j]){
                    update(set,i,j,field,dist);    
                }
            }
        }
        
    }
    
    
    

}
//Powered by KawigiEdit 2.1.4 (beta) modified by pivanof!

大神的代码(Java):

import java.util.*; 
public class GooseInZooDivTwo { 
  boolean visited[][] = new boolean[51][51]; 
   
    public int count(String[] field, int dist) { 
        int res = 0; 
        int mod = 1000000007; 
        int N = field.length;  
        int M = field[0].length();  
          
         
        int block = 0;  
        for (int i = 0; i < N; i++) 
          for (int j = 0; j < M; j++)  
            if (field[i].charAt(j) == 'v' && !visited[i][j]) { 
              fill(i, j, field, dist); 
              block++;  
            } 
        //System.out.println(block);  
        if (block > 0) { 
          res = 1;  
          for (int i = 0; i < block; i++) { 
            res = (res*2)%mod;  
          } 
          res --;  
        } 
        return res; 
    } 

    private void fill(int i, int j, String[] field, int dist) { 
      int N = field.length;  
        int M = field[0].length(); 
         
        visited[i][j] = true;  
      for (int x = 0; x < N; x++) 
        for (int y = 0; y < M; y++) 
          if (Math.abs(x-i) + Math.abs(y-j) <= dist && field[x].charAt(y) == 'v' && !visited[x][y]) { 
            fill(x, y, field, dist);  
          } 
  } 

} 


// Powered by FileEdit
// Powered by CodeProcessor

大神的代码(C++):

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
 
using namespace std;
 
#define ALL(v) (v).begin(),(v).end()
#define RALL(v) (v).rbegin(),(v).rend()
#define UNIQ(v) sort(ALL(v)),v.erase(unique(ALL(v)),(v).end())
 
typedef long long ll;
typedef long double ld;
 
class GooseInZooDivTwo {
public:
  int count(vector <string>, int);
};
 
vector< pair<int, int> > bds;
vector<bool> used;
int dist;
 
void dfs(int v)
{
  used[v] = 1;
  for (size_t i = 0; i < bds.size(); ++i)
  {
    if (!used[i] && abs(bds[v].first-bds[i].first) + abs(bds[v].second-bds[i].second) <= dist)
      dfs(i);
  }
}
 
int GooseInZooDivTwo::count(vector <string> field, int _dist) 
{
  dist = _dist;
  for (size_t i = 0; i < field.size(); ++i)
    for (size_t j = 0; j < field[0].size(); ++j)
      if (field[i][j] == 'v')
        bds.push_back(make_pair(i,j));
  int n = bds.size();
  used.resize(n, 0);
  long long d = 0;
  for (int i = 0; i < n; ++i)
    if (!used[i])
    {
      ++d;
      dfs(i);
    }
  if (!d)
    return 0;
  long long ans = 1;
  for (int i = 0; i < d; ++i)
    ans = (ans*2) % 1000000007;
  ans = (ans-1+1000000007) % 1000000007;
  return (int)ans;
}
 
 
//Powered by [KawigiEdit] 2.0!

 分析:

  算法:Greedy, Simple Math

  对比:

    1.C++大神考虑得更全面。ans=(ans-1+1000000007)%1000000007;虽然2^n不可能达到1000000008的倍数。

    2.C++大神的vector<pair<int,int>>用得出神入化啊,菜鸟表示学习了。

    3.我和java大神基本上一样的。

  问题:这道题贪心使用在哪里?

      

posted on 2013-07-04 09:00  wzhscript  阅读(203)  评论(0编辑  收藏  举报