zoukankan      html  css  js  c++  java
  • SRM DIV2 578 GooseInZooDivTwo

    算法思考过程:

    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大神基本上一样的。

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

          

  • 相关阅读:
    Django MVC与MTV概念 Ajax、分页实现
    Django F查询Q查询Only与Defel
    Django ORM 操作
    已有数据的表添加自增主键
    java随机字符串+校验位
    mysql日志触发器
    dad
    jsp自定义标签
    php-pfm指定配置文件
    type
  • 原文地址:https://www.cnblogs.com/wang3/p/3163877.html
Copyright © 2011-2022 走看看