`
linx_bupt
  • 浏览: 15674 次
  • 来自: 北京
社区版块
存档分类
最新评论

POJ_1009_EdgeDetection分析

 
阅读更多

题目是对RLE压缩的图像进行边缘检测。

RLE是游程编码的意思(Run length edcoding),比如555555根据游程编码可以编码成5 6。在代码中可以用控制符来区分编码字节和重复次数。

题目大意如下:

输入一张或多张游程编码的压缩图片,输出该图片的边缘检测的图片。其中,输入时0表示没有下一张图片,0 0表示本张图片输入结束。

 

算法思路:

1)输入的为RLE压缩图像,需要将图像还原为bitmap的形式才能计算图像的边缘检测。

缺点:如果图像过大,比如达到了10^9个像素,那么需要创建的二位数组将会超出题目给定内存的限制

优化:建立一个view,大小为3*column,这样每次只用存3行的像素,并且对于中间的一行,上下文都是可见的,因此可以做到逐行解析,逐行处理

2)根据上面的改进方法,无论多大的图像只要时间足够,都是可以计算出边缘检测图形的,但是也有缺点

缺点:逐行处理所花的时间会随着图像的增大而变多,当图形足够大的时候,时间会增到到超出限制。如果图像中重复单元很多,存在很大的优化空间。

优化:检测输入的像素,如果输入的重复像素过多,可以计算出有多少像素的边缘检测值是一样的,那么可以省去这些像素的计算

 

整体代码如下:

import java.io.*;

public class Main {
	
	public static void main(String[] args) throws IOException, InvalidInputException {
		BufferedReader stdin = 
            new BufferedReader(
                new InputStreamReader(System.in));
		
		String line = null;
		String[] input = null;
		while (true) {
			line = stdin.readLine();
			int width = Integer.parseInt(line);
			if (width == 0) break;
			
			int[][] matrix = new int[3][width];
			RlePair pair = new RlePair(0, 0);
			int value = 0;
			int times = 0;
			int index = 0;
			int delta = 0;
			int diffValue = 0;
			for (int i = 0; i < 3; i++) {
				for (int j = 0; j < width; j++) {
					matrix[i][j] = -1; // -1 is null
				}
			}
			
			while (true) {
				line = stdin.readLine();
				input = line.split("\\s");
				if (input.length != 2) {
					throw new InvalidInputException();
				}
				value = Integer.parseInt(input[0]);
				times = Integer.parseInt(input[1]);
				if (value == 0 && times == 0) break;
				int currRow = 0;
				//-----------------------------------------------------------------
				// 算法主体
				for (int n = 0; n < times; n++) {
					currRow = (index + n) / width + 1 - delta;
					if (currRow == 3) {
						for (int i = 0; i < width; i++) {
							if (matrix[1][i] == -1) break;
							diffValue = max(width, matrix, i);
							if (diffValue == pair.value) {
								pair.times++;
							} else {
								if (pair.times != 0) System.out.println(pair.toString());
								pair = new RlePair(diffValue, 1);
							}
						}
						
						delta++;
						
						for (int i = 0; i < 2; i++) {
							for (int j = 0; j < width; j++) {
								matrix[i][j] = matrix[i + 1][j];
							}
						}
						currRow = (index + n) / width + 1 - delta;
						
						if (n / width > 2 && (times - n) / width > 1) {
								int d = (times - n) / width - 1;
								pair.times += d * width;
								n += d * width;
								delta += d;
						}
					}
					matrix[currRow][(index + n) % width] = value;
				}
				index += times;
			}
			// 算法主体
			//-----------------------------------------------------------------
			// 最后几行的处理
			for (int i = 0; i < width; i++) {
				if (matrix[1][i] == -1) break;
				diffValue = max(width, matrix, i);
				if (diffValue == pair.value) {
					pair.times++;
				} else {
					if (pair.times != 0) System.out.println(pair.toString());
					pair = new RlePair(diffValue, 1);
				}
			}
			
			for (int i = 0; i < 2; i++) {
				for (int j = 0; j < width; j++) {
					matrix[i][j] = matrix[i + 1][j];
				}
			}
			
			for (int j = 0; j < width; j++) {
				matrix[2][j] = -1;
			}
			
			for (int i = 0; i < width; i++) {
				if (matrix[1][i] == -1) break;
				diffValue = max(width, matrix, i);
				if (diffValue == pair.value) {
					pair.times++;
				} else {
					if (pair.times != 0) System.out.println(pair.toString());
					pair = new RlePair(diffValue, 1);
				}
			}
			
			System.out.println(pair.toString());
			System.out.println("0 0");
			// 最后几行的处理
			//-----------------------------------------------------------------
		}
		
		if (stdin != null) {
			stdin.close();
			stdin = null;
		}
	}

	private static int max(int width, int[][] matrix, int index) {
		// TODO Auto-generated method stub
		//  0:   0  1  2
		//  1:   3     4
		//  2:   5  6  7
		int[] x = new int[] {-1, -1, -1, -1, -1, -1, -1, -1}; // 8
		if (index - 1 >= 0) {
			x[0] = matrix[0][index - 1];
			x[3] = matrix[1][index - 1];
			x[5] = matrix[2][index - 1];
		}
		x[1] = matrix[0][index];
		x[6] = matrix[2][index];
		if (index + 1 < width) {
			x[2] = matrix[0][index + 1];
			x[4] = matrix[1][index + 1];
			x[7] = matrix[2][index + 1];
		}
		
		int maxDiff = 0;
		for (int n : x) {
			if (n != -1) {
				maxDiff = maxDiff > Math.abs(matrix[1][index] - n) ? maxDiff : Math.abs(matrix[1][index] - n);
			}
		}
		
		return maxDiff;
	}
}

class RlePair {
	int value;
	int times;
	
	public RlePair(int value, int times) {
		this.value = value;
		this.times = times;
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return this.value + " " + this.times;
	}
	
}

@SuppressWarnings("serial")
class InvalidInputException extends Exception {
	
}

 

让我郁闷的是,代码提交poj一直是runtime error,而自己测试确没什么问题。我测试的环境是jdk7.0,不知道和jdk升级是否有关系。。。(狡辩一下:我练习的目标是训练自己思考算法的感觉的,此题的目的已经达到,如果poj能多给一点错误信息我是很乐意让这道题accept的:))

 

0
1
分享到:
评论

相关推荐

    POJ1009-Edge Detection

    【压缩包子文件的文件名称列表】:"POJ1009-Edge Detection.cpp"、"POJ1009-Edge Detection.doc" "POJ1009-Edge Detection.cpp"是解决该问题的C++源代码文件,很可能包含了实现边缘检测算法的函数和主程序逻辑。...

    poj_1699.rar_1699_poj_poj1699

    通过阅读和分析poj_1699.txt文件,我们可以学习到如何分析问题、设计算法、编写代码以及验证解决方案的正确性,这对于提高编程和算法能力非常有帮助。同时,这也是一个很好的实例,展示了在面对实际问题时,如何运用...

    poj2775.rar_poj_poj 27_poj27_poj2775

    标签"poj poj_27 poj27 poj2775"进一步确认了这是一道关于POJ平台的编程挑战,其中"poj_27"可能是表示第27类问题或者某种分类,而"poj27"可能是对"poj2775"的简写。 压缩文件中的"www.pudn.com.txt"可能是一个链接...

    poj_2682(3).rar_C++ 数组扩充_poj 26_poj 2682_poj26

    标题中的"poj_2682(3).rar"是一个指向编程竞赛问题的引用,通常这类问题在网站如POJ(Programming Online Judge)上出现,供程序员解决并提交代码进行测试。这个问题的编号是2682,可能涉及到特定的数据结构或算法...

    poj1009 Edge Detection 可以直接AC的

    poj1009 Edge Detection 可以直接AC的

    Poj_1102_.rar_poj11

    标题"Poj_1102_.rar_poj11"暗示了这是一个关于解决Poj_1102问题的资源包,通常在编程竞赛或在线判题系统如POJ(Problem Set of Judge Online)上遇到。POJ是中国的一个在线编程训练平台,提供了各种算法题目供用户...

    POJ_3131.zip_POJ 八数码_poj

    标题中的“POJ_3131.zip_POJ 八数码_poj”指的是一个与编程竞赛网站POJ(Problem Set Algorithm)相关的项目,具体是针对3131号问题的解决方案,该问题涉及到了八数码游戏。八数码游戏,又称滑动拼图,是一个经典的...

    poj_3613解题报告

    2遍dp poj_3613解题报告 poj_3613解题报告

    poj_3310.rar_3310_poj

    【标题】"poj_3310.rar_3310_poj"是一个与编程竞赛相关的压缩包,其中包含了对POJ(Problem Online Judge)3310问题的解决方案和详细解析。POJ是一个著名的在线编程竞赛平台,提供各种算法题目供参赛者练习和提交...

    ACM.zip_ACM_poj_poj3187_poj3669

    标题 "ACM.zip_ACM_poj_poj3187_poj3669" 提供的信息表明,这个压缩包包含的是与ACM(国际大学生程序设计竞赛)相关的编程题目解决方案,具体是POJ(Programming Online Judge)平台上的两道题目,编号分别为poj3187...

    1010_stamps.zip_1010_POJ 1010_poj_poj stamps_poj10

    《POJ 1010 Stamps:解题思路与陷阱分析》 POJ 1010,也被称为“邮票问题”,是编程竞赛中的一道经典题目,旨在考察参赛者的动态规划和数学思维能力。这个题目在编程爱好者中具有较高的知名度,因为它涉及到有趣的...

    pku_poj_2187.rar_poj 2187_凸包问题

    标题中的“pku_poj_2187.rar_poj 2187_凸包问题”表明这是一个关于北京大学(Peking University, PKU)编程竞赛平台POJ上的第2187题,题目主要涉及凸包问题。描述中的“O(nlogn)凸包问题 poj2187”提示我们解决这个...

    poj_1002_487.rar_poj 1002

    【标题】"poj_1002_487.rar_poj 1002"指的是北京大学在线编程平台上的第1002道题目,这道题目涉及到计算机科学中的算法设计与实现,特别是字符串处理和哈希映射。在这个问题中,我们需要编写一个程序,该程序能够...

    POJ3277.rar_3277 poj_poj3277_多个面积_线段树

    标题中的“POJ3277.rar_3277 poj_poj3277_多个面积_线段树”是指一个与编程竞赛相关的压缩文件,特别提到了POJ(Problemset Online Judge)的第3277号问题。POJ是一个著名的在线编程竞赛平台,参与者需要解决各种...

    C_(POJ_1854)(分治).cpp

    C_(POJ_1854)(分治).cpp

    poj1990.rar_POJ 19_poj_poj19

    《POJ 1990:树状数组解题策略详解》 在编程竞赛的世界里,POJ(Programming Online Judge)是一个备受瞩目的在线评测系统,它提供了丰富的编程题目供参赛者挑战。其中,编号为1990的题目是一道涉及数据结构与算法...

    jihe.rar_2289_POJ 3714_poj3714_poj3714 Ra_visual c

    标题中的"jihe.rar_2289_POJ 3714_poj3714_poj3714 Ra_visual c" 提到了一个压缩文件,可能包含有关编程竞赛或算法解决的资源,特别是与POJ(Problem On Judge)平台上的问题3714相关的。"Ra_visual c"可能指的是...

    D_(POJ_1723)(思维)(sort).cpp

    D_(POJ_1723)(思维)(sort).cpp

    D_(POJ_1723)(思维)(第k大数).cpp

    D_(POJ_1723)(思维)(第k大数).cpp

    POJ_keptsl6_C++_

    现在,让我们逐个分析压缩包中的文件名,尽管没有提供具体的题目和代码细节,但我们可以基于常见的POJ题目类型推测可能涉及的知识点: 1. 13295.cpp:可能是一个关于排序或查找的问题,因为这类问题在编程竞赛中很...

Global site tag (gtag.js) - Google Analytics