#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;
}
程序员面试金典: 9.9 递归和动态规划 9.7颜色填充
最新推荐文章于 2020-04-15 15:33:42 发布