程序员面试金典: 9.9 递归和动态规划 9.7颜色填充

#include <iostream>
#include <stdio.h>

using namespace std;

/*
问题:编写函数,实现许多图片编辑软件都支持的“填充颜色”功能。给定一个屏幕(以二维数组表示,元素为颜色值)、一个点和
      和一个新的颜色值,将新颜色值填入这个点的周围区域,直到原来的颜色值全部都改变。
分析:应该是经典的图形学算法:种子填充算法。该题目所要求的是从给定点开始,将整个屏幕区域的颜色都变为新的颜色。
      种子填充可以采用上下左右的递归来填充。对于当前点,将当前点填充好后,设置当前点访问过,然后获取当前点上下左右4个点,
	  对这4个点中没有访问过的点都进行递归处理。
	  可以以采用广度优先搜索来做。

输入:
5(宽) 5(高)
1(起点的横坐标) 3(起点的纵坐标)
1(新的颜色值)
输出:(整个区域填充后结果)
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
*/

const int MAXSIZE = 1000;
int gColorArray[MAXSIZE][MAXSIZE];//颜色数组
int gVisitArray[MAXSIZE][MAXSIZE];//访问数组,0表示未访问,1表示访问
//遍历的上下左右4个顶点走法
int gNext[4][2] = 
{
	{0 , 1},
	{0 , -1},
	{-1, 0},
	{1,0}
};

//填充颜色
void fillColor(int x , int y , int width , int height, int newColor)
{
	int tempX ;
	int tempY;
	//遍历上下左右4个点
	for(int i = 0 ; i < 4 ; i++)
	{
		tempX = x + gNext[i][0];
		tempY = y + gNext[i][1];
		//判断候选点是否超出范围,是否访问过,如果已经访问,就不再处理
		if(tempX < 0 || tempX > width || tempY < 0 || tempY > height || 1 == gVisitArray[tempX][tempY])
		{
			continue;
		}
		//接下来开始设置当前点已访问,并重新设置颜色,然后递归处理
		gVisitArray[tempX][tempY] = 1;
		gColorArray[tempX][tempY] = newColor;
		fillColor(tempX , tempY , width , height , newColor);
	}
}

void print(int width , int height)
{
	for(int i = 0 ; i < width ; i++ )
	{
		for(int j = 0 ; j < height ; j++)
		{
			if(j)
			{
				cout << " " << gColorArray[i][j];
			}
			else
			{
				cout <<  gColorArray[i][j];
			}
		}
		cout << endl;
	}
	cout << endl;
}

void process()
{
	int width , height;
	int beginX , beginY;
	int newColor;
	while(cin >> width >> height)
	{
		cin >> beginX >> beginY;
		cin >> newColor;
		if(beginX < 0 || beginY < 0 || beginX > width || beginY > beginY || newColor > 255 || newColor < 0)
		{
			cout << "Input is wrong,please input again" << endl;
			continue;
		}
		memset(gColorArray , 0 , sizeof(gColorArray) ); // 初始化颜色数组每个颜色为黑色(即0)
		memset(gVisitArray , 0 , sizeof(gVisitArray));
		//下面使用给定的颜色进行填充
		fillColor(beginX , beginY , width , height , newColor);
		print(width , height);
	}
}

int main(int argc, char* argv[])
{
	process();
	getchar();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值