zoukankan      html  css  js  c++  java
  • 北大ACM 1009题—Edge Detection

    Edge Detection
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 15307   Accepted: 3445

    Description

    IONU Satellite Imaging, Inc. records and stores very large images using run length encoding. You are to write a program that reads a compressed image, finds the edges in the image, as described below, and outputs another compressed image of the detected edges. 
    A simple edge detection algorithm sets an output pixel's value to be the maximum absolute value of the differences between it and all its surrounding pixels in the input image. Consider the input image below: 

    The upper left pixel in the output image is the maximum of the values |15-15|,|15-100|, and |15-100|, which is 85. The pixel in the 4th row, 2nd column is computed as the maximum of |175-100|, |175-100|, |175-100|, |175-175|, |175-25|, |175-175|,|175-175|, and |175-25|, which is 150. 
    Images contain 2 to 1,000,000,000 (109) pixels. All images are encoded using run length encoding (RLE). This is a sequence of pairs, containing pixel value (0-255) and run length (1-109). Input images have at most 1,000 of these pairs. Successive pairs have different pixel values. All lines in an image contain the same number of pixels. 

    Input

    Input consists of information for one or more images. Each image starts with the width, in pixels, of each image line. This is followed by the RLE pairs, one pair per line. A line with 0 0 indicates the end of the data for that image. An image width of 0 indicates there are no more images to process. The first image in the example input encodes the 5x7 input image above. 

    Output

    Output is a series of edge-detected images, in the same format as the input images, except that there may be more than 1,000 RLE pairs. 

    Sample Input

    7
    15 4
    100 15
    25 2
    175 2
    25 5
    175 2
    25 5
    0 0
    10
    35 500000000
    200 500000000
    0 0
    3
    255 1
    10 1
    255 2
    10 1
    255 2
    10 1
    255 1
    0 0
    0
    

    Sample Output

    7
    85 5
    0 2
    85 5
    75 10
    150 2
    75 3
    0 2
    150 2
    0 4
    0 0
    10
    0 499999990
    165 20
    0 499999990
    0 0
    3
    245 9
    0 0
    0
    

    Hint

    A brute force solution that attempts to compute an output value for every individual pixel will likely fail due to space or time constraints. 

    Source

    /*
    *突破点在于Input的pair,pair上限只有1000,数据量是最少的,因此只能利用这点去解题。
    *要利用pair,就必须懂得“跳跃式编码”,就是说只在像素发生变化的位置进行编码,
    *而像素没有变化的位置则其编码值与其左边的像素一致。
    */
    
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    const int size=1000;  //每幅图片的pair上限
    int width;  //Map的宽
    int total=0;  //像素点总个数
    
    typedef class OutMapPix
    {
    	public:
    		int pos;    //OutMap中每个像素点的顺序位置,pos从1开始
    		int code;   //OutMap中每个像素点对应InMap的编码
    }Pix;
    
    int InMapPair[size][2];  //InMapPair[][0]为像素值,InMapPair[][1]为InMapPair[][0]连续出现的个数
    Pix OutMap[size*8];    //每个pix都依赖其周围的8个点编码
    
    int cmp(const void* a,const void* b);  //快排比较规则
    int GetValue(int pos);  //返回第pos个像素点的像素值
    int GetCode(int pos);   //返回第pos个像素点的编码
    
    int main(int k)
    {
    	while(cin>>width && width)
    	{
    		int pairv,pairt;
    		k=total=0;
    		while(cin>>pairv>>pairt && pairt)
    		{
    			InMapPair[k][0]=pairv;
    			InMapPair[k++][1]=pairt;
    			total+=pairt;
    		}
    		int PairNum=k;  //pair的个数
    
    		cout<<width<<endl;
    
    		int pos=1;  //当前处理的像素点的位置
    		k=0; //OutMap[]指针
    		for(int p=0;p<=PairNum;p++)
    		{
    			int row=(pos-1)/width;  //得到pos在二维图对应的坐标
    			int col=(pos-1)%width;
    
    			for(int i=row-1;i<=row+1;i++)        //枚举(row,col)周围及其自身共9个点(x,y)
    				for(int j=col-1;j<=col+1;j++)
    				{
    					int tpos=i*width+j;  //得到(x,y)的顺序位置
    
    					if(i<0 || j<0 || j>=width || tpos>=total)
    						continue;
    
    					OutMap[k].pos=tpos+1;
    					OutMap[k++].code=GetCode(tpos+1);  //对发生变化的像素点的附近8个点编码
    				}
    
    			pos+=InMapPair[p][1];  //跳跃,确定下一个像素发生变化的点的位置
    		}
    
    		qsort(OutMap,k,sizeof(Pix),cmp);  //对OutMap根据顺序位置
    
    		/*OutPut*/
    
    		Pix temp=OutMap[0];
    		for(int i=0;i<k;i++)
    		{
    			if(temp.code==OutMap[i].code)
    				continue;
    			cout<<temp.code<<' '<<OutMap[i].pos-temp.pos<<endl;
    			temp=OutMap[i];
    		}
    		cout<<temp.code<<' '<<total-temp.pos+1<<endl;
    		cout<<"0 0"<<endl;
    
    	}
    	cout<<0<<endl;
    
    	return 0;
    }
    
    
    /*快排比较规则*/
    int cmp(const void* a,const void* b)
    {
    	Pix* x=(Pix*)a;
    	Pix* y=(Pix*)b;
    	return x->pos - y->pos;
    }
    
    /*返回第pos个像素点的像素值*/
    int GetValue(int pos)
    {
    	int i=0,p=0;
    	while(p<pos)
    		p+=InMapPair[i++][1];
    
    	return InMapPair[i-1][0];
    }
    
    /*返回第pos个像素点的编码*/
    int GetCode(int pos)
    {
    	int code=GetValue(pos);
    	int MaxAbs=0;
    
    	int row=(pos-1)/width;
    	int col=(pos-1)%width;
    
    	for(int i=row-1;i<=row+1;i++)
    		for(int j=col-1;j<=col+1;j++)
    		{
    			int tpos=i*width+j;
    
    			if(i<0 || j<0 || j>=width || tpos>=total || tpos==pos-1)  //tpos==pos-1为中心的像素点,即当前待编码的点
    				continue;
    
    			int tcode=GetValue(tpos+1);
    
    			if(MaxAbs<abs(tcode-code))   //注意取绝对值
    				MaxAbs=abs(tcode-code);
    		}
    	return MaxAbs;
    }


  • 相关阅读:
    【T-SQL】分布抽取部分数据
    【Tip】如何让引用的dll随附的xml注释文档、pdb调试库等文件不出现在项目输出目录中
    【手记】F5调试报"由于缺少调试目标xxx无法开始调试xxx设置OutputPath和AssemblyName"
    【手记】未能从程序集System.Net.Http.Formatting中加载类型System.Net.Http.Formatting.FormUrlEncodedMediaTypeFormatter
    摄影基础知识入门
    测试开发进阶必备(附源码)---Dubbo 接口测试技术
    App自动化之dom结构和元素定位方式的详细内容(不看后悔)
    接口自动化测试 | JsonPath 与 Mustache 请求传参的模板化技术
    一文搞定自动化测试框架 RESTAssured 实践(三):对 Response 结果导出
    一文搞定 REST Assured 实践(二):断言实现
  • 原文地址:https://www.cnblogs.com/finlay/p/3234722.html
Copyright © 2011-2022 走看看