Go: // AOJ 1160: How Many Islands? http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1160

package main

import (
	"bufio"
	"container/list"
	"fmt"
	"os"
	"strconv"
)

var SEA = 0
var LAND = 1

func nextInt(sc *bufio.Scanner) int {
	sc.Scan()
	v, _ := strconv.Atoi(sc.Text())
	return v
}

func discoverIslands(M, V [][]int, H, W int) int {
	// 島を探す
	queue := list.New()
	islands := 0
	for i := 1; i <= H; i++ {
		for j := 1; j <= W; j++ {
			// 訪問済みの土地ならスキップ
			if V[i][j] == 1 {
				continue
			}

			// 訪問中の土地が海なら訪問済みにしてスキップ
			if M[i][j] == SEA {
				V[i][j] = 1
				continue
			}

			// 未訪問の陸地が見つかったので
			// 島の数を1つ増やし、この陸地から辿れる陸地を訪問していく
			islands++
			queue.PushBack([]int{i, j})

			for queue.Len() > 0 {
				cur := queue.Remove(queue.Front()).([]int)
				h, w := cur[0], cur[1]
				if V[h][w] == 1 {
					continue
				}
				V[h][w] = 1

				// 全方向に未訪問の陸地がないか探索
				for v := -1; v <= 1; v++ {
					for l := -1; l <= 1; l++ {
						dh := h + v
						dw := w + l
						if M[dh][dw] == LAND && V[dh][dw] == 0 {
							queue.PushBack([]int{dh, dw})
						}
					}
				}
				/*
					if M[h-1][w] == LAND {
						queue.PushBack([]int{h - 1, w})
					}
					if M[h-1][w+1] == LAND {
						queue.PushBack([]int{h - 1, w + 1})
					}
					if M[h][w+1] == LAND {
						queue.PushBack([]int{h, w + 1})
					}
					if M[h+1][w+1] == LAND {
						queue.PushBack([]int{h + 1, w + 1})
					}
					if M[h+1][w] == LAND {
						queue.PushBack([]int{h + 1, w})
					}
					if M[h+1][w-1] == LAND {
						queue.PushBack([]int{h + 1, w - 1})
					}
					if M[h][w-1] == LAND {
						queue.PushBack([]int{h, w - 1})
					}
					if M[h-1][w-1] == LAND {
						queue.PushBack([]int{h - 1, w - 1})
					}
				*/
			}
		}
	}
	return islands
}

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)

	for {
		W, H := nextInt(sc), nextInt(sc)

		if W == 0 && H == 0 {
			break
		}
		// Initialize map and visted list
		M := make([][]int, H+2)
		V := make([][]int, H+2)
		for i := 0; i < H+2; i++ {
			M[i] = make([]int, W+2)
			V[i] = make([]int, W+2)
		}
		for i := 1; i <= H; i++ {
			for j := 1; j <= W; j++ {
				M[i][j] = nextInt(sc)
			}
		}

		islands := discoverIslands(M, V, H, W)

		fmt.Println(islands)
	}
}

C++: #include<stdio.h>
void draw(int x,int y);
int w,h,c[51][51];
int main(){
	int i,j;
	int count;
	scanf("%d %d",&w,&h);
	while((w!=0)&&(h!=0)){
		count=0;
		for(j=0;j<h;j++){
			for(i=0;i<w;i++){
				scanf("%d",&c[j][i]);
			}
		}
		for(i=0;i<w;i++){
			c[h][i]=0;
		}
		for(i=0;i<h;i++){
			c[i][w]=0;
		}
		for(i=0;i<w;i++){
			for(j=0;j<h;j++){
				if(c[j][i]==1){
					count++;
					draw(j,i);
				}
			}
		}
		printf("%d\n",count);
		scanf("%d %d",&w,&h);
	}
	return 0;
}
void draw(int x,int y){
	int i,j;
	c[x][y]=0;
	for(i=0;i<3;i++){
		for(j=0;j<3;j++){
			if(c[x-1+i][y-1+j]==1){
				draw(x-1+i,y-1+j);
			}
		}
	}
}

C++: #include<bits/stdc++.h>
using namespace std;

// macro
#define rep(i,n) for(i=0;i<n;i++)
#define ll long long
#define all(v) v.begin(), v.end()

// code starts
void dfs(vector<vector<int>> &c,int nx,int ny)
{
  int i,j;
  c[nx][ny]=0;
  for(i=-1;i<=1;i++)for(j=-1;j<=1;j++)
  {
    if(i==0&&j==0)continue;
    if(c[nx+i][ny+j]==1)
    {
      dfs(c,nx+i,ny+j);
    }
  }
}

int main()
{
  int w,h;cin>>w>>h;
  while(w!=0||h!=0)
  {
    int i,j;
    vector<vector<int>> c(h+2,vector<int>(w+2,0));
    rep(i,h)rep(j,w)cin>>c[i+1][j+1];
    int ans=0;
    rep(i,h)rep(j,w)
    {
      if(c[i+1][j+1]==1)
      {
        dfs(c,i+1,j+1);
        ans++;
      }
    }
    cout<<ans<<endl;
    cin>>w>>h;
  }
}

C++: #include<cstdio>
using namespace std;
void func(int,int);
int a,b;
int sima[51][51];
int cnt;
int main(void)
{
	int i,j,x,y;
	scanf("%d",&a);
	scanf("%d",&b);
	while(!(b==0 && a==0)){
		
		for(i=0;i<b;i++){
			for(j=0;j<a;j++){
				scanf("%d",&sima[i][j]);
			}
		}
		cnt=0;
		for(i=0;i<b;i++){
			for(j=0;j<a;j++){
				if(sima[i][j]==1){
					func(i,j);
					cnt++;
				}
			}
		}
		printf("%d\n",cnt);
		scanf("%d",&a);
		scanf("%d",&b);
	}
	return 0;
}
void func(int y,int x)
{
	if(y-1>=0){
		if(sima[y-1][x]==1){
			sima[y-1][x]=0;
			func(y-1,x);
		}
	}
	if(x-1>=0){
		if(sima[y][x-1]==1){
			sima[y][x-1]=0;
			func(y,x-1);	
		}
	}
	if(y+1<=b){
		if(sima[y+1][x]==1){
			sima[y+1][x]=0;
			func(y+1,x);
		}
	}
	if(x+1<=a){
		if(sima[y][x+1]==1){
			sima[y][x+1]=0;
			func(y,x+1);
		}
	}
	if(y-1>=0 && x+1<=a){
		if(sima[y-1][x+1]==1){
			sima[y-1][x+1]=0;
			func(y-1,x+1);
		}
	}
	if(y-1>=0 && x-1>=0){
		if(sima[y-1][x-1]==1){
			sima[y-1][x-1]=0;
			func(y-1,x-1);
		}
	}
	if(y+1<=b && x+1<=a){
		if(sima[y+1][x+1]==1){
			sima[y+1][x+1]=0;
			func(y+1,x+1);
		}
	}
	if(y+1<=b && x-1>=0){
		if(sima[y+1][x-1]==1){
			sima[y+1][x-1]=0;
			func(y+1,x-1);
		}
	}
}

C++: #include <bits/stdc++.h>
using namespace std;
int main(void){
    int w,h;
    while (cin>>w>>h) {
        if (w==0&&h==0) {
            break;
        }
        char c;
        std::vector<vector<char>> vec(h,vector<char>(w));
        bool seen[h][w];
        for (int i=0;i<h;i++) {
            for (int j=0;j<w;j++) {
                cin>>c;
                vec[i][j]=c;
                seen[i][j]=false;
            }
        }
        int count=0;
        for (int i=0;i<h;i++) {
            for (int j=0;j<w;j++) {
                if (vec[i][j]=='1'&&seen[i][j]==false) {
                    seen[i][j]=true;
                    std::stack<pair<int,int>> stk;
                    stk.push(make_pair(i,j));
                    while (stk.size()!=0) {
                        int x=stk.top().first;
                        int y=stk.top().second;
                        if (x+1<h&&seen[x+1][y]==false&&vec[x+1][y]=='1') { //下
                            stk.push(make_pair(x+1,y));
                            seen[x+1][y]=true;
                        } else if (y+1<w&&seen[x][y+1]==false&&vec[x][y+1]=='1') { //右
                            stk.push(make_pair(x,y+1));
                            seen[x][y+1]=true;
                        } else if (x+1<h&&y-1>=0&&seen[x+1][y-1]==false&&vec[x+1][y-1]=='1') { //左下
                            stk.push(make_pair(x+1,y-1));
                            seen[x+1][y-1]=true;
                        } else if (x+1<h&&y+1<w&&seen[x+1][y+1]==false&&vec[x+1][y+1]=='1') { //右下
                            stk.push(make_pair(x+1,y+1));
                            seen[x+1][y+1]=true;
                        } else if (x-1>=0&&y-1>=0&&seen[x-1][y-1]==false&&vec[x-1][y-1]=='1') { //左上
                            stk.push(make_pair(x-1,y-1));
                            seen[x-1][y-1]=true;
                        } else if (x-1>=0&&y+1<w&&seen[x-1][y+1]==false&&vec[x-1][y+1]=='1') { //右上
                            stk.push(make_pair(x-1,y+1));
                            seen[x-1][y+1]=true;
                        } else if (x-1>=0&&seen[x-1][y]==false&&vec[x-1][y]=='1') { //上
                            stk.push(make_pair(x-1,y));
                            seen[x-1][y]=true;
                        } else if (y-1>=0&&seen[x][y-1]==false&&vec[x][y-1]=='1') { //左
                            stk.push(make_pair(x,y-1));
                            seen[x][y-1]=true;
                        } else {
                            stk.pop();
                        }
                    }
                    count++;
                }
            }
        }
        cout<<count<<endl;
    }
}