声明:感谢:燕哥,兴趣读者可关注 V信公众号:燕哥带你学算法
尊重原作者劳动:http://mp.weixin.qq.com/s/P_0azRNETLoyCOFYGu7lgQ
博主在燕哥的文章中发现了很细微的BUG,这里更正,并献上两份Codes
第一种适用于群岛数量一般的情况,第二种适用于群岛范围极大情况;从效率出发,考虑实情,第二种并无应用场景。
/*
如下所示的Map中,0代表海水,1代表岛屿,其中每一个岛屿与其八领域的区间的小岛能相连组成岛屿群。写代码,统计Map中岛屿个数。
Map :
0 0 0 0 0 1 0 1
0 1 0 0 0 0 0 0
0 1 1 0 0 0 0 0
0 0 0 0 0 0 1 0
1 0 1 0 0 1 0 0
1 0 0 0 0 0 0 0
*/
#include <iostream>
#include <queue>
#include <fstream>
#define MAX 10
using namespace std;
typedef struct
{
int i;
int j;
} position;
void SearchMap(int a[MAX][MAX], int Line, int Column, int i, int j, int Cnt)
{
queue<position> qu;
vector<position> Verify;// 用于验证,存储已经扫描过的点
position p;
p.i = i;
p.j = j;
qu.push(p);
Verify.push_back(p);// 用于验证,存储已经扫描过的点
int Veri_Cnt = 0;
int ii, jj, flag = Cnt;
while(!qu.empty())
{
qu.pop();
for(ii = p.i -1; ii <= p.i +1 ;ii++) // 动态搜索所有8邻域
for(jj = p.j -1; jj <= p.j +1; jj++)
{
if( (ii != i || jj != j) && ii >= 0 && ii < Line && jj >= 0 && jj < Column && a[ii][jj] == 1)
{
a[ii][jj] = Cnt; // 用于标记
vector<position>::iterator it; // 验证
for(it = Verify.begin(); it != Verify.end(); ++it)
{
if ((*it).i != ii || (*it).j != jj)
++Veri_Cnt;
}
if (Veri_Cnt == Verify.size())
{
Verify.push_back(p);
p.i = ii;
p.j = jj;
qu.push(p);
}
}
++Veri_Cnt;
}
}
}
int Count(int a[MAX][MAX], int Line, int Column)
{
int i, j, Cnt = 0;
for(i = 0; i < Line; i++)
for(j = 0; j < Column; j++)
{
if(a[i][j] == 1)
{
++Cnt;
SearchMap(a, Line, Column, i, j, Cnt);
}
}
return Cnt;
}
int main()
{
int iVal, index = 0, n = 0;
int Line = 0, Column = 0; // 行列编号
fstream ifs1("execute.stdin");
int a[MAX][MAX];
// 先确定一行有多长
while ( ifs1.get() != '\n')
{
++n;
}
n = (n+1)/2;
ifs1.close();
fstream ifs("execute.stdin");
while(ifs >> iVal)
{
Column = (index)%n;
if(Column == 0 && index > 0)
++Line;
a[Line][Column] = iVal;
++index;
}
ifs.close();
int Cnt = Count(a, Line+1 ,Column+1);
cout << Cnt;
system("pause");
return 0;
}
/*
如下所示的Map中,0代表海水,1代表岛屿,其中每一个岛屿与其八领域的区间的小岛能相连组成岛屿群。写代码,统计Map中岛屿个数。
Map :
0 0 0 0 0 1 0 0
0 1 0 0 0 0 0 0
0 1 1 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 0 0 0 1 0 0
1 0 0 0 0 0 0 0
*/
#include <iostream>
#include <queue>
#include <fstream>
#define MAX 10
using namespace std;
typedef struct
{
int i;
int j;
} position;
void SearchMap(int a[MAX][MAX], int Line, int Column, int i, int j, int Cnt)
{
queue<position> qu;
vector<position> Verify;// 用于验证,存储已经扫描过的点
position p;
a[i][j] = 2;// 染色 任意非1的数
p.i = i;
p.j = j;
qu.push(p);
Verify.push_back(p);// 用于验证循环次数
int Veri_Cnt = 0;
int ii, jj, flag = Cnt;
while(!qu.empty())
{
qu.pop();
for(ii = p.i -1; ii <= p.i +1 ;ii++) // 动态搜索所有8邻域
for(jj = p.j -1; jj <= p.j +1; jj++)
{
if( (ii != i || jj != j) && ii >= 0 && ii < Line && jj >= 0 && jj < Column && a[ii][jj] == 1)
{
a[ii][jj] = 2; // 染色 任意非1的数
p.i = ii;
p.j = jj;
qu.push(p);
}
++Veri_Cnt;
}
}
}
int Count(int a[MAX][MAX], int Line, int Column)
{
int i, j, Cnt = 0;
for(i = 0; i < Line; i++)
for(j = 0; j < Column; j++)
{
if(a[i][j] == 1)
{
++Cnt;
SearchMap(a, Line, Column, i, j, Cnt);
}
}
return Cnt;
}
int main()
{
int iVal, index = 0, n = 0;
int Line = 0, Column = 0; // 行列编号
fstream ifs1("execute.stdin");
int a[MAX][MAX];
// 先确定一行有多长
while ( ifs1.get() != '\n')
{
++n;
}
n = (n+1)/2;
ifs1.close();
fstream ifs("execute.stdin");
while(ifs >> iVal)
{
Column = (index)%n;
if(Column == 0 && index > 0)
++Line;
a[Line][Column] = iVal;
++index;
}
ifs.close();
int Cnt = Count(a, Line+1 ,Column+1);
cout << Cnt;
system("pause");
return 0;
}