POJ1009

来源:互联网 发布:儿童围棋教学软件 编辑:程序博客网 时间:2024/05/16 19:51

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.


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------********************************************************************************************

看到好多人说POJ里面水题多,瞬间感觉自己又给大家拖后腿了。。。第一天,撸了一下午,洗出来一个结果TLE,然后想了一晚上,也没有什么方法;第二天看了大神的各种分析,感觉可以了,还是照着大神代码写的,撸了一下午,终于AC了。。。


1、这道题难就难在,数据可能会很大,如果蛮力解决的话,不是TLE就是MLE;找到一个方法很重要,网上大神有许多方法,我选择了比较简单的一个方法。

2、通过例题就可以感觉到,由于输入中有很多数据是连续没有变化的,所以在输出的时候可以看到也是有很多连续的数字;由分析可以看出,每次输出变化的时候,是在输入串的开头以及开头位置的四周八个位置处。因此,我们需要记录每个数据串开头及其周围共九个位置,记录这些位置的信息(位置以及与周围数据差的最大值),然后按位置进行排序,可以得到输出串的两端。。。这样,总共不超过1000对数据,完全不会超出限制。

感觉数据变量太多了,写的代码好凌乱啊,而且容易出错。。。

#include<stdio.h>#include<stdlib.h>#define SIZE 1000int pair[SIZE][2];typedef struct omg{int pos;int pixel;}omg;omg outpix[8*SIZE];int total,width,size1,size2;int get_value(int pos){int i=0,p=0;while(p<pos){p+=pair[i++][1];}return pair[i-1][0];}int get_code(int pos){int max=0;int row,col,t_pos;int i,j;int value=get_value(pos);int t_value;row=(pos-1)/width;col=(pos-1)%width;for(i=row-1;i<=row+1;i++){for(j=col-1;j<=col+1;j++){t_pos=i*width+j+1;if(i<0||j<0||j>=width||t_pos>total||t_pos==pos)continue;t_value=get_value(t_pos);if(max<abs(t_value-value))max=abs(t_value-value);}}return max;}int cmp(const void* a,const void* b){omg *x=(omg *)a;omg *y=(omg *)b;return x->pos-y->pos;}int main(){int pixel,length;int row,col;int i,j,k;int cur;while(scanf("%d",&width)!=EOF){if(width==0)break;size1=0;total=0;while(scanf("%d%d",&pixel,&length)!=EOF){if(pixel==0&&length==0)break;pair[size1][0]=pixel;pair[size1++][1]=length;total+=length;}printf("%d\n",width);cur=1;size2=0;for(k=0;k<=size1;k++){row=(cur-1)/width;col=(cur-1)%width;for(i=row-1;i<=row+1;i++){for(j=col-1;j<=col+1;j++){int top=i*width+j+1;if(i<0||j<0||j>=width||top>total)continue;outpix[size2].pos=top;outpix[size2++].pixel=get_code(top);}}cur+=pair[k][1];}qsort(outpix,size2,sizeof(omg),cmp);omg temp=outpix[0];for(i=0;i<size2;i++){if(outpix[i].pixel!=temp.pixel){printf("%d %d\n",temp.pixel,outpix[i].pos-temp.pos);temp=outpix[i];}}printf("%d %d\n",temp.pixel,total-temp.pos+1);printf("0 0\n");}printf("0\n");return 0;} 


0 0
原创粉丝点击