为编程难题提出算法建议
Suggest Algorithm for the programming puzzle
给出以下矩阵
10001
10100
00000
00000
00111
00100
00100
点击一下,像素填充工具将每个黑色像素变成白色像素,直到没有一个黑色像素可以从前一个像素到达。一个像素与另一个像素的连接方式多达八种:北、南、东、西和四条对角线。
拼图链接为http://www.gild.com/challenges/details/295#
这就是我解决它的方法。谁能告诉我这个问题属于哪一类算法?
#include <stdio.h>
#include <vector>
#include <fstream>
#include <sstream>
#include <iostream>
#include <deque>
typedef std::vector<std::vector<bool> > table_t;
class Solver {
public:
Solver(int H, int W): _height(H),
_width(W),
T(H, std::vector<bool>(W)),
num_of_clicks(0){
}
~Solver() {
}
void ReadFile(std::ifstream &ifs){
int row = 0, col = 0;
std::string file_line;
while( ifs.good() ) {
std::getline(ifs,file_line);
for ( std::string::const_iterator it = file_line.begin(); it != file_line.end(); ++it) {
if ( *it - '0' == 1 ) {
T[row][col++] = true;
} else {
T[row][col++] = false;
}
}
col = 0;
row++;
}
ifs.close();
}
void solve() {
for ( int row = 0; row < _height; ++row) {
for ( int col = 0; col < _width; ++col) {
if ( T[row][col] == true )
continue;
neighbours.clear();
num_of_clicks++;
neighbours.push_back(std::make_pair(row,col));
while ( !neighbours.empty()) {
std::pair<int,int> elem = neighbours.front();
neighbours.pop_front();
int R = elem.first;
int C = elem.second;
west (R, C);
east (R, C);
north (R, C);
south (R, C);
north_west (R, C);
south_west (R, C);
south_east (R, C);
north_east (R, C);
}
} // colum loop ends here
} // row loop ends here
std::cout << num_of_clicks << std::endl;
}
private:
int _height;
int _width;
table_t T;
std::deque<std::pair<int,int> > neighbours;
int num_of_clicks;
void west(int row, int col) {
if ( col - 1 >= 0 && T[row][col - 1 ] == false ) {
T[row][col - 1 ] = true;
neighbours.push_back(std::make_pair(row, col - 1));
}
}
void east(int row, int col) {
if ( col + 1 < _width && T[row][col + 1 ] == false ) {
T[row][col + 1 ] = true;
neighbours.push_back(std::make_pair(row, col + 1));
}
}
void north(int row, int col) {
if ( row - 1 >= 0 && T[row - 1][col] == false ) {
T[row - 1][col] = true;
neighbours.push_back(std::make_pair(row - 1, col));
}
}
void south(int row, int col) {
if ( row + 1 < _height && T[row + 1][col] == false ) {
T[row + 1][col]= true;
neighbours.push_back(std::make_pair(row + 1, col ));
}
}
void north_west(int row, int col) {
if (row - 1 >= 0 && col - 1 >= 0 &&
T[row - 1][col - 1] == false ) {
T[row - 1][col - 1] = true;
neighbours.push_back(std::make_pair(row - 1, col - 1));
}
}
void south_west(int row, int col) {
if ( row + 1 < _height && col - 1 >= 0 &&
T[row + 1][ col - 1] == false) {
T[row + 1][ col - 1] = true;
neighbours.push_back(std::make_pair(row + 1, col - 1));
}
}
void south_east(int row, int col) {
if ( row + 1 < _height && col + 1 < _width &&
T[row + 1][col + 1] == false ){
T[row + 1][col + 1] = true;
neighbours.push_back(std::make_pair(row + 1, col + 1));
}
}
void north_east(int row, int col) {
if ( row - 1 >= 0 && col + 1 < _width &&
T[row - 1][col + 1] == false ) {
T[row - 1][col + 1] = true;
neighbours.push_back(std::make_pair(row - 1, col + 1 ));
}
}
};
int main ( int argc, char **argv) {
int H = 0;
int W = 0;
std::ifstream input(argv[1]);
if ( input.peek() == EOF ) {
return 1;
}
// Read the first line.
std::string file_line;
std::getline(input,file_line);
std::istringstream iss;
iss.clear();
iss.str(file_line);
// Get the height and width of the image.
iss >> H >> W;
Solver s(H,W);
s.ReadFile(input);
s.solve();
return 0;
}
这个洪水填充操作是通过膨胀进行形态重建的经典应用(标记图像为黑色,具有单个白色起始像素,掩模图像为原始图像的逆)。比较L. vincent关于高效实现的论文(看起来很像您的实现)和O. Eidheim出色的介绍性演讲。
它被称为连接组件标签。注意这是它的一般化版本,这是维基百科条目
相关文章:
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 基于ELO的团队匹配算法
- C++选择排序算法中的逻辑错误
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- C++A*算法并不总是在路径中具有目标节点
- 排序算法c++
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 构建可组合有向图(扫描仪生成器的汤普森构造算法)
- 了解算法的性能差异(如果以不同的编程语言实现)
- 编程作业:机器人遗传算法
- 以C++元编程风格实现 RLE 算法
- 用于优化存储/运行时算法的元编程,C++
- 算法输出正确答案,但编程挑战给了我错误的答案
- 基于定点算法的编译时元编程.乘法溢出
- 在C++中对Dijkstra算法进行编程
- 在编程中,这两项任务中的任何一项都有算法方法吗
- 为编程难题提出算法建议
- 为a*算法编程一个启发式函数
- 这是最大子数组和算法的动态编程版本的工作方式吗?