poj1009

来源:互联网 发布:最大公约数 java 编辑:程序博客网 时间:2024/06/06 13:11
Edge Detection
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 12975 Accepted: 2872

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

715 4100 1525 2175 225 5175 225 50 01035 500000000200 5000000000 03255 110 1255 210 1255 210 1255 10 00

Sample Output

785 50 285 575 10150 275 30 2150 20 40 0100 499999990165 200 4999999900 03245 90 00

一种转换方法:一张图片以类似矩阵的形式存储,从头开始依次给出矩阵里出现的数字和次数,这是原始矩阵。然后从第一个数字开始,与周围八个数做减法之后取绝对值。把绝对值最大的数字就是新矩阵里这个数字对应位置的值。最后还是以题中给出旧矩阵的形式输出新矩阵。对于全部矩阵只有一种数的可以直接输出0加个数。对于同一个数字占了两行以上个数的,中间的数字也是直接为0;

这道题我没AC,因为超时。我是去网上找了代码,一行一行看了一遍以后。自己重新写了一遍,还是超时。一共花了一天时间在上面。果断先不理它。

我参考的代码:

#include<stdio.h>#include<stdlib.h>#include<string.h>#define row_num (box_num/width)const int NUM=1005;int data[NUM][2];const int dir[8][2]={{-1,-1},{-1,0},{-1,+1},{0,-1},{0,1},{+1,-1},{+1,0},{+1,+1}};int num;int width;int box_num;int getValue(int index,int i,int j){if(index<0){while(index){if(j>0){j--;index++;}else if(j==0){i--;if(i<0)return -1;j=data[i][1];}} }else if(index>0){while(index){if(j<data[i][1]-1){j++;index--;continue;}else if(j==data[i][1]-1){i++;if(i==num)return -1;j=0;index--;}}}return data[i][0];}bool isLegal(int pos,int k){int row=pos/width;int col=pos%width;if(row+dir[k][0]>=0&&row+dir[k][0]<row_num&&col+dir[k][1]>=0&&col+dir[k][1]<width)return true;return false;}void solve(){int count=0;int last_max=-1;int pos=0;for(int i=0;i<num;i++){for(int j=0;j<data[i][1];j++,pos++){int max=-1;for(int k=0;k<8;k++){if(isLegal(pos,k)==false)continue;   int index=dir[k][0]*width+dir[k][1]; //相对于自己的下标偏移值   int value=getValue(index,i,j);   if(value!=-1)   {   if(value-data[i][0]>max)   max=value-data[i][0];   else if(data[i][0]-value>max)   max=data[i][0]-value;   //printf("value dif %d %d %d\n",i,data[i][0],value);   }}if(data[i][1]>1000&&pos-2*width>pos-j && pos+2*width<pos-j+data[i][1]){int det=data[i][1]-2*width-j;pos+=det-1;count+=det;j+=det-1;continue;}if(last_max==-1){last_max=max;count++;}else if(last_max==max){count++;}else if(last_max!=max){printf("%d %d\n",last_max,count);count=1;last_max=max;}} }printf("%d %d\n",last_max,count);}int main(){freopen("input.txt","r",stdin);int value,n; while(scanf("%d",&width)!=EOF){printf("%d\n",width);if(width==0)break;num=0;box_num=0;while(scanf("%d %d",&value,&n)&&(value!=0||n!=0))        {data[num][0]=value;data[num++][1]=n;box_num+=n;}if(num==1)printf("0 %d\n",data[0][1]);elsesolve(); printf("0 0\n");}return 0;}

我的代码

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>int pair_num, width, heighth, pair[1001][2], addtion[8][2]={ {-1,-1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}};int getvalue(int x, int y, int index){if(index < 0){while(index!=0){if(y > 0){y--;index++;}else if(y <= 0){x--;y = pair[x][1]-1;index++;}}}else if(index > 0){while(index != 0){if(y < pair[x][1] - 1 ){y++;index--;}else if(y >= pair[x][1] - 1){x++;y = 0;index--;}}}return pair[x][0];}bool check(int pos, int k){int row, col;row = pos / width;col = pos % width;if( row+addtion[k][0]>=0 && row+addtion[k][0]<heighth && col+addtion[k][1]>=0 && col+addtion[k][1]<width) return true;else return false;}void workout(){int pos=0, max=-1, lastmax=-1, count=0, m=0, max1=-1, flag=0;for(int i=0;i<=pair_num;i++){for(int j=0; j<pair[i][1];j++,pos++){for(int k=0;k<=7;k++){if( check(pos, k) == false) continue;int index = addtion[k][0] *  width + addtion[k][1];int tmp = getvalue( i, j, index);if(flag==0){flag=1;max1=fabs( tmp - pair[i][0] );}if( fabs( tmp - pair[i][0] ) > max1)max1 = fabs( tmp - pair[i][0] );}if(pair[i][1]>1000&&pos-2*width>pos-j && pos+2*width<pos-j+pair[i][1])              {                  int det=pair[i][1]-2*width-j;                  pos+=det-1;                  count+=det;                  j+=det-1;                  continue;              }  flag=0;max=max1;if(lastmax == -1){count=1;lastmax=max;}else if(max == lastmax){count++;}if(max != lastmax ){printf("%d %d\n",lastmax,count);count=1;lastmax=max;max=-1;}}}printf("%d %d\n",lastmax,count);printf("0 0\n");}int main(){freopen("input.txt","r",stdin);int a, n, num=0;int total=0;while(1){scanf("%d",&width);if(width == 0) break;printf("%d\n",width);while(1){scanf("%d %d", &a, &n);if(a == 0 && n == 0) break;pair[num][0]=a;pair[num++][1]=n;total+=n;}pair_num=num-1;heighth=total/width;if(pair_num==1){printf("0 %d",pair[0][1]);}else{workout();}num=0;total=0;}return 0;}

优化那段我是直接copy的。我参考的代码好像是把个数大于1000的拿来优化,应该大于两行多的就能这样优化。但事实是他的过了,我的没过。肯定哪里有问题。

原创粉丝点击