基于图的性质:
1.四领域(上、下、左、右(递归))染色
void floodFill4(vector<vector<int>>& screen,int x,int y,int newColor,int oldColor){
int m = screen.size();//m代表行
int n = screen[0].size();//n代表列
if(x >= 0 && x < n && y>=0 && y < m && screen[y][x] == oldColor && screen[y][x] != newColor){//判断(越界、是否需要改色情况)
screen[y][x] = newColor;//[y][x]等于新元素
floodFill4(screen,x+1,y,newColor,oldColor);//函数调用[y][x]的右边
floodFill4(screen,x-1,y,newColor,oldColor);//函数调用[y][x]的左边
floodFill4(screen,x,y+1,newColor,oldColor);//函数调用[y][x]的下边
floodFill4(screen,x,y-1,newColor,oldColor);//函数调用[y][x]的上边
}
}
vo
2.八领域(上、下、左、右、左上、左下、右上、右下(递归))染色
void floodFill8(vector<vector<int>> & screen,int x,int y,int newColor,int oldColor){
int h = screen.size();//h代表行
int w = screen[0].size();//w代表列
if(x >= 0 && x < w && y >= 0 && y < h && screen[y][x] == oldColor && screen[y][x] != newColor){//判断(越界、是否需要改色情况)
screen[y][x] = newColor;//染色
floodFill8(screen,x+1,y,newColor,oldColor);//右染色
floodFill8(screen,x-1,y,newColor,oldColor);//左染色
floodFill8(screen,x,y+1,newColor,oldColor);//下 染色
floodFill8(screen,x,y-1,newColor,oldColor);//上染色
floodFill8(screen,x+1,y+1,newColor,oldColor);//右下染色
floodFill8(screen,x+1,y-1,newColor,oldColor);//右上染色
floodFill8(screen,x-1,y+1,newColor,oldColor);//左下染色
floodFill8(screen,x-1,y-1,newColor,oldColor);//左上染色
}
}
3.扫描线(先扫描一行或者一列内的连通像素,然后再上下行或者左右列扫描)染色
void floodFillScanline(int x,int y,int newColor,int oldColor,vector<vector<int>>& screen,int w,int h) {
if(newColor == oldColor) return ;
if(screen[y][x] != oldColor) return ;
int x1=x;
/*1*/while (x1 < w && screen[y][x1] == oldColor){
screen[y][x1] = newColor;
x1++;
}
x1 = x - 1;
/*2*/while (x1 >= 0 && screen[y][x1] == oldColor){
screen[y][x1] = newColor;
x1--;
}
x1 = x;
/*3*/while (x1 < w && screen[y][x1] == newColor){
if(y < h - 1 && screen[y + 1][x1] == oldColor)
floodFillScanline(x1,y+1,newColor,oldColor,screen,w,h);
x1++;
}
x1 = x - 1;
/*4*/while(x1 >= 0 && screen[y][x1] == newColor){
if(y < h - 1 && screen[y+1][x1] == oldColor)
floodFillScanline(x1,y+1,newColor,oldColor,screen,w,h);
x1--;
}
x1 = x;
/*5*/while (x1 < w && screen[y][x1] == newColor){
if(y > 0 && screen[y - 1][x1] == oldColor)
floodFillScanline(x1,y-1,newColor,oldColor,screen,w,h);
x1++;
}
x1 = x - 1;
/*6*/while(x1 >= 0 && screen[y][x1] == newColor){
if(y > 0 && screen[y - 1][x1] == oldColor)
floodFillScanline(x1,y-1,newColor,oldColor,screen,w,h);
x1--;
}
}
源代码:
1.
#include<bits/stdc++.h>
using namespace std;
void floodFill4(vector<vector<int>>& screen,int x,int y,int newColor,int oldColor){
int m = screen.size();//m代表行
int n = screen[0].size();//n代表列
if(x >= 0 && x < n && y>=0 && y < m && screen[y][x] == oldColor && screen[y][x] != newColor){//判断(越界、是否需要改色情况)
screen[y][x] = newColor;//[y][x]等于新元素
floodFill4(screen,x+1,y,newColor,oldColor);//函数调用[y][x]的右边
floodFill4(screen,x-1,y,newColor,oldColor);//函数调用[y][x]的左边
floodFill4(screen,x,y+1,newColor,oldColor);//函数调用[y][x]的下边
floodFill4(screen,x,y-1,newColor,oldColor);//函数调用[y][x]的上边
}
}
void printScreen(const vector<vector<int>>& screen){
for(int i=0;i< screen.size();i++){
for(int j=0;j<screen[i].size();j++){
cout<<screen[i][j]<<" ";
}
cout<<endl;
}
}
int main(){
vector<vector<int>> screen = {
{1,1,1,1},
{1,1,0,1},
{1,0,1,1}
};
int x=1;
int y=1;
int newColor =2;
int oldColor = screen[y][x];
cout<<"屏幕:\n";
printScreen(screen);
floodFill4(screen,x,y,newColor,oldColor);
cout<<"\n屏幕2:\n";
printScreen(screen);
}
2.
#include<bits/stdc++.h>
using namespace std;
void floodFill8(vector<vector<int>> & screen,int x,int y,int newColor,int oldColor){
int h = screen.size();//h代表行
int w = screen[0].size();//w代表列
if(x >= 0 && x < w && y >= 0 && y < h && screen[y][x] == oldColor && screen[y][x] != newColor){//判断(越界、是否需要改色情况)
screen[y][x] = newColor;//染色
floodFill8(screen,x+1,y,newColor,oldColor);//右染色
floodFill8(screen,x-1,y,newColor,oldColor);//左染色
floodFill8(screen,x,y+1,newColor,oldColor);//下 染色
floodFill8(screen,x,y-1,newColor,oldColor);//上染色
floodFill8(screen,x+1,y+1,newColor,oldColor);//右下染色
floodFill8(screen,x+1,y-1,newColor,oldColor);//右上染色
floodFill8(screen,x-1,y+1,newColor,oldColor);//左下染色
floodFill8(screen,x-1,y-1,newColor,oldColor);//左上染色
}
}
void printScreen(const vector<vector<int>>& screen){
for(int i=0;i< screen.size();i++){
for(int j=0;j<screen[i].size();j++){
cout<<screen[i][j]<<" ";
}
cout<<endl;
}
}
int main(){
vector<vector<int>> screenBuffer = {
{1,1,1,1},
{1,1,0,1},
{1,0,1,1}
};
int x = 1;
int y = 1;
cout<<"1:"<<endl;
printScreen(screenBuffer);
floodFill8(screenBuffer,x,y,2,1);
cout<<"2:"<<endl;
printScreen(screenBuffer);
}
3.
#include<bits/stdc++.h>
using namespace std;
void floodFillScanline(int x,int y,int newColor,int oldColor,vector<vector<int>>& screen,int w,int h) {
if(newColor == oldColor) /*判断:新颜色=旧颜色(无意义)*/return ;//退出
if(screen[y][x] != oldColor)/*判断:sreceen[y][x]!=旧颜色(无意义)*/ return ;//退出
int x1=x;//创建x1=x(临时变量)
/*1*/while (x1 < w && screen[y][x1] == oldColor){//循环:如果没有到底、没有染色,会一直循环
screen[y][x1] = newColor;//染色
x1++;//向下移动
}
x1 = x - 1;//x1=x-1
/*2*/while (x1 >= 0 && screen[y][x1] == oldColor){//循环:如果没有到顶、没有染色,会一直循环
screen[y][x1] = newColor;//染色
x1--;//向上移动
}
x1 = x;//x1=x
/*3*/while (x1 < w && screen[y][x1] == newColor){//循环:寻找新的节点
if(y < h - 1 && screen[y + 1][x1] == oldColor)//判断:是不是新的节点继续染色
floodFillScanline(x1,y+1,newColor,oldColor,screen,w,h);//调用函数
x1++;//向下移动
}
x1 = x - 1;//x1=x-1
/*4*/while(x1 >= 0 && screen[y][x1] == newColor){//循环:寻找新的节点
if(y < h - 1 && screen[y+1][x1] == oldColor)//判断:是不是新的节点
floodFillScanline(x1,y+1,newColor,oldColor,screen,w,h);//调用函数继续染色
x1--;//向上移动
}
x1 = x;//x1=x
/*5*/while (x1 < w && screen[y][x1] == newColor){//循环:寻找新的节点
if(y > 0 && screen[y - 1][x1] == oldColor)//判断:是不是新的节点
floodFillScanline(x1,y-1,newColor,oldColor,screen,w,h);//调用函数继续染色
x1++;//向下移动
}
x1 = x - 1;//x1=x-1
/*6*/while(x1 >= 0 && screen[y][x1] == newColor){//循环:寻找新的节点
if(y > 0 && screen[y - 1][x1] == oldColor)//判断:是不是新的节点
floodFillScanline(x1,y-1,newColor,oldColor,screen,w,h);//调用函数继续染色
x1--;//向上移动
}
}
void printScreen(const vector<vector<int>>& screen){
for(int i=0;i< screen.size();i++){
for(int j = 0;j < screen[i].size();j++){
cout<<screen[i][j]<<" ";
}
cout<<endl;
}
}
int main(){
vector<vector<int>> screen = {
{1,1,1,1},
{1,1,0,1},
{1,0,1,1}
};
int x = 2;
int y = 2;
int newColor = 2;
int oldColor = screen[y][x];
int w = screen[0].size();
int h = screen.size();
cout<<"1:\n";
printScreen(screen);
floodFillScanline(x,y,newColor,oldColor,screen,w,h);
cout<<"2:\n";
printScreen(screen);
}