您的位置:首页 > 编程语言 > Go语言

SRM DIV2 578 GooseInZooDivTwo

2013-07-04 09:00 363 查看
算法思考过程:

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

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

      
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: