华为OD机试真题】68、矩阵扩散

package main

import (
	"errors"
	"fmt"
	"strconv"
	"strings"
)

type point struct {
	x     int
	y     int
	value int
}

type image struct {
	w        int
	h        int
	allPoint int
	points   [][]*point
}

func (i *image) newImage(m, n int) *image {
	img := make([][]*point, m)
	for i1 := 0; i1 < m; i1++ {
		img[i1] = make([]*point, n)
		for j := 0; j < n; j++ {
			itemPoint := &point{
				x:     i1,
				y:     j,
				value: 0,
			}
			img[i1][j] = itemPoint
		}
	}

	return &image{
		w:        m,
		h:        n,
		allPoint: m * n,
		points:   img,
	}
}

func (i *image) getPointValue(x, y int) (int, error) {
	for i1 := 0; i1 < i.w; i1++ {
		for j := 0; j < i.h; j++ {
			if i1 == x && j == y {
				return i.points[i1][j].value, nil
			}
		}
	}

	return 0, errors.New("not found")
}

func (i *image) setPointValue(p1 *point) (*image, error) {
	for i1 := 0; i1 < i.w; i1++ {
		for j := 0; j < i.h; j++ {
			if i1 == p1.x && j == p1.y {
				i.points[i1][j].value = p1.value
				return i, nil
			}
		}
	}

	return nil, errors.New("not found")
}

func (i *image) setPointsValue(list []*point, value int) {
	for _, p := range list {
		p.value = value
		i.setPointValue(p)
	}
}

func (i *image) countWaitePoints() (count int) {
	for i1 := 0; i1 < i.w; i1++ {
		for j := 0; j < i.h; j++ {
			if i.points[i1][j].value == 1 {
				count++
			}
		}
	}
	return
}

func (i *image) isAllWaite() bool {
	if i.countWaitePoints() == i.allPoint {
		return true
	}
	return false
}

// 获取一个点周围的非白色像素点
func (i *image) listAroundNotWaitePoints(p1 *point) []*point {
	list := make([]*point, 0)
	centerX, centreY := p1.x, p1.y
	for x := -1; x <= 1; x++ {
		for y := -1; y <= 1; y++ {
			if x != 0 && y != 0 {
				continue
			}

			itemX := centerX + x
			itemY := centreY + y
			//溢出
			if itemX*itemY < 0 {
				continue
			}
			if value, err := i.getPointValue(itemX, itemY); err == nil {
				if value != 1 {
					list = append(list, &point{
						x:     itemX,
						y:     itemY,
						value: i.points[itemX][itemY].value,
					})
				}
			}

		}
	}

	return list
}

func (i *image) listWaitePoints() []*point {
	list := make([]*point, 0)

	for i1 := 0; i1 < i.w; i1++ {
		for j := 0; j < i.h; j++ {
			if i.points[i1][j].value == 1 {
				list = append(list, &point{
					x:     i1,
					y:     j,
					value: i.points[i1][j].value,
				})
			}
		}
	}

	return list
}

func (i *image) timer(count int) int {
	if i.isAllWaite() {
		return count
	} else {
		count++

		waitePoints := i.listWaitePoints()
		for _, waitePoint := range waitePoints {
			//开始膨胀
			if notWaitePoints := i.listAroundNotWaitePoints(waitePoint); len(notWaitePoints) > 0 {
				i.setPointsValue(notWaitePoints, 1)
			}
		}
		return i.timer(count)
	}

}

func main() {
	var inputStr string
	fmt.Scan(&inputStr)
	inputStrList := strings.Split(inputStr, ",")
	inputIntList := make([]int, len(inputStrList))
	for i, s2 := range inputStrList {
		inputIntList[i], _ = strconv.Atoi(s2)
	}

	var m, n int
	m = inputIntList[0]
	n = inputIntList[1]

	myImage := new(image)
	img := myImage.newImage(m, n)
	img.setPointValue(&point{
		x:     inputIntList[2],
		y:     inputIntList[3],
		value: 1,
	})
	img.setPointValue(&point{
		x:     inputIntList[4],
		y:     inputIntList[5],
		value: 1,
	})

	count := img.timer(0)
	fmt.Println(count)

}

总结:矩阵扩散在图形图像中被称为膨胀,结合openCV中对图片和像素点的定义,在程序中我定义了两种struct: image 和point,并实现了膨胀系数为1的膨胀算法。在通过递归的方式不断执行膨胀操作,知道全部点都变白,则停止递归,每次膨胀时计数器timer加一,递归结束后返回timer.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值