FloodFill 统计子图形的两种方式
来源:互联网 发布:网络监控头更改ip 编辑:程序博客网 时间:2024/05/29 12:26
Flood Fill算法是 图论 中非常重要的一种算法思想:找到一个符合要求的点,按照某种方式对该点进行扩充,标记该点,对扩充的点进行重复操作。
Flood Fill的两种典型的实现方式是bfs和dfs,下面两道统计 子图形 的题目,分别用bfs和dfs实现
1. http://222.200.185.45/7148
描述:给出图形,问其中有多少个矩形,多少个圆形,多少个三角形。
注意题目要求:每个图形至少包含15个‘#’,空缺最多占10%,任意两个图形不共边,不共点(这点非常重要,也就是说每一个图形都是完全孤立的)
思路:用bfs进行Flood Fill,对于每个图形,统计其中‘#’的个数,算出包含该图形的最小矩形的大小,根据图形占矩形的百分比判断该图形的形状。
#include <cstdio>#include <cstring>#include <queue>using namespace std;struct Point{int x, y;Point() {}Point(int _x, int _y): x(_x), y(_y) {}};int r, c, re, tr, ci;char data[510][510];int dir[8][2] = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};void floodfill(int x, int y){queue <Point> Q;Q.push(Point(x,y));data[x][y] = '.';int cnt = 1;int minx = x, maxx = x, miny = y, maxy = y;Point cur, nxt;while (!Q.empty()){cur = Q.front();Q.pop();for (int i = 0; i < 8; ++ i){nxt = Point(cur.x+dir[i][0], cur.y+dir[i][1]);if (data[nxt.x][nxt.y] == '#'){Q.push(nxt);data[nxt.x][nxt.y] = '.';cnt += 1;if (minx > nxt.x) minx = nxt.x;if (maxx < nxt.x) maxx = nxt.x;if (miny > nxt.y) miny = nxt.y;if (maxy < nxt.y) maxy = nxt.y;}}}if (cnt < 15) return;double area = 0.0 + (maxx-minx+1)*(maxy-miny+1);if (cnt / area > 0.875) re += 1;else if (cnt / area > 0.6) ci += 1;else if (cnt / area > 0.1) tr += 1;}int main(){while (~scanf("%d %d", &r, &c)){re = tr = ci = 0;for (int i = 1; i <= r; ++ i){scanf("%s", data[i]+1);data[i][c+1] = '.';}for (int i = 1; i <= r; ++ i)for (int j = 1; j <= c; ++ j)if (data[i][j] == '#')floodfill(i, j);printf("Rectangle: %d\nCircle: %d\nTriangle: %d\n\n", re, ci, tr);}}
2.
1008. Triangle, rectangle and square
Description
We represent a binary image with a 2D array of bits. The bits consist of only 0 and 1. The eight surrounding bits around a bit are its connected neighbors. The image has several shapes that consist of connected 1's. The shapes can be triangles, rectangles, squares. Now given an image, you are to count the number of each kind of shape. If a shape is a square, don't count it as a rectangle. All 1's on a side of any shape lie on a straight line. We ensure that no any two shapes are connected, and any given shape contains 0's inside it.
Input
The input file will consist of several test cases.
The first line of each case is two positive integers M and N (3<=M, N<=100), which means that the image grid has M rows and N columns. Then M lines follow, each line with a string of N characters. The characters would only be "0" or "1".
The input is ended with M=0 and N=0.
Output
For each test case, output on a single line the number of each kind of shape, with the format "Triangle: A, Rectangle: B, Square: C". A, B and C are respectively the numbers of triangle, rectangle and square.
Sample Input
4 8000101110011010101010101111101114 60001000010100001000000000 0
Sample Output
Triangle: 1, Rectangle: 1, Square: 0Triangle: 0, Rectangle: 0, Square: 1
Problem Source: wuhefeng
注意题目要求:任意两个图形不共边,不共点(这点非常重要,也就是说每一个图形都是完全孤立的)。每个图形中间用空白填充。
思路:用dfs进行Flood Fill,对于每个图形,记录它的顶点,根据顶点的个数判断是三角形还是矩形,如果是矩形,再根据图形的边长判断是长方形还是正方形。
#include <cstdio>#include <vector>#include <cmath>#include <cstring>using namespace std;typedef pair<int,int> pii;int r, c, tr, re, sq;char data[110][110];int dir[8][2] = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};vector <pii> point;void floodfill(int x, int y){point.push_back(pii(x,y));int tx, ty;for (int i = 0; i < 8; ++ i){tx = x + dir[i][0];ty = y + dir[i][1];if (data[tx][ty] == '1'){data[tx][ty] = '0';while (data[tx+dir[i][0]][ty+dir[i][1]] == '1'){tx += dir[i][0];ty += dir[i][1];data[tx][ty] = '0';}floodfill(tx,ty);}}}void judge(){if (point.size() == 4) tr += 1;else if (point.size() == 5){if (abs(point[0].first-point[2].first) == abs(point[0].second-point[2].second))sq += 1;else if (point[0].first == point[2].first || point[0].second == point[2].second)sq += 1;else re += 1;}}int main(){while (true){tr = re = sq = 0;memset(data, '0', sizeof(data));scanf("%d %d", &r, &c);if (r == 0 && c == 0) break;for (int i = 1; i <= r; ++ i){scanf("%s", data[i]+1);data[i][c+1] = '0';}for (int i = 1; i <= r; ++ i){for (int j = 1; j <= c; ++ j){if (data[i][j] == '1'){point.clear();floodfill(i, j);judge();}}}printf("Triangle: %d, Rectangle: %d, Square: %d\n", tr, re, sq);}}
- FloodFill 统计子图形的两种方式
- TI Stellaris图形库的两种文字显示方式
- sql语句统计求和两种 写的方式
- 小猫统计:主从表编辑的两种关联方式
- 两种方式实现图形图片
- Spring MVC jsp 嵌入子页面的两种方式
- 移除子控件两种方式的区别
- vue向子组件传递参数的两种方式
- SQL 按月统计(两种方式)
- floodfill算法的几种实现
- 统计查询-根据条件进行count的两种实现方式- oracle
- Hadoop开篇之Mapreduce实现多类别流量统计的两种实现方式
- 统计查询-根据条件进行count的两种实现方式- oracle
- 图形API的两种模式
- iOS 获取Interface Builder上的子控制器的两种方式
- 父、子进程同步的5个例程的两种实现方式
- js与jquery两种不同的方式获得父元素、删除子元素
- 将ios代码在后台(子线程)执行的两种简单方式
- centos5.6下kvm的安装/桥接设置/虚拟机创建及运行
- MAC下Android的Eclipse开发环境的搭建
- ListView拖动时背景黑色的问题
- MultiByteToWideChar
- sql之编辑数据
- FloodFill 统计子图形的两种方式
- 指针排序
- Delphi版本号对照
- activity以Dialog形式显示
- iOS 单例模式
- Android开发推荐资料大合集
- PTA是什么?BT-WIFI共存
- quest3d通道英汉对照部分
- 这学期看的书