zoukankan      html  css  js  c++  java
  • POJ 1009 Edge Detection

    Edge Detection
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 22153   Accepted: 5201

    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.

    WARNING

    说明:本程序不能在POJ上AC,并不是本程序有问题,而是POJ太不严谨(系统后台的测试数据绝对有问题!),能不能AC取决于测试数据的完备程度!要相信自己,不要过于相信平台!

    随便给出一组测试数据:(从网上搜一个在POJ上AC的代码,用下组数据跑一下,绝对给你惊喜!错误的程序竟然能在POJ上AC,不是你的眼睛看错了,而是POJ的测试数据有问题,太水!)

    5
    6 4
    7 5
    9 11
    0 0
    0

    源码如下:本程序虽然不能在POJ上AC,但不是本程序的问题,经过多次反复测试,本程序均能得到正确的结果!不多说了,自己看一下,跑一下,才能明白生活中很多坑!

    参考:http://blog.csdn.net/v5zsq/article/details/46562881#cpp

      1 #include<iostream>
      2 #include<fstream>
      3 #include<string>
      4 //#include<cmath>
      5 #include<algorithm>
      6 using namespace std;
      7 //pl对的个数,题目中明确表示不会超过1000个,只要设置大于1000即可
      8 const int pl=1002;
      9 /*
     10     说明:1.对于一副图片来说,第一行输入是图片的宽度,理解为一行有多少个像素
     11           2.之后每行输入两个整数,表示像素的连续段,第一个整数是连续段起始像素的值
     12           第二整数表示该像素重复的次数,即连续段的长度
     13           3.本程序中连续段描述为pl对,有n个连续段表示有n个pl对
     14 */
     15 /*
     16     mapin[][0] 表示当前pl对的像素值
     17     mapin[][1] 表示当前pl对之前的所有pl对的长度和
     18                可理解为,当前pl对应的连续段起始像素位置之前有多少个像素
     19 */
     20 int mapin[1002][2];
     21 /*
     22     width 图片的宽度,像素矩阵每行像素的数目
     23     foot  图片的高度,像素矩阵一共有多少行
     24     plzhi 每组测试用例中pl对的数目
     25     sum      图片的像素数目
     26 */
     27 int width,foot;
     28 int plzhi;
     29 int sum;
     30 /*
     31     pixInfo 输出数组的类型
     32     loc     像素的位置
     33     pix     该位置像素处理后的结果
     34     mapout  输出数组
     35 */
     36 struct pixInfo
     37 {
     38     int loc;
     39     int pix;
     40 };
     41 pixInfo mapout[pl*9];
     42 //根据位置,返回像素值
     43 int locpix(int loc)
     44 {
     45     for(int i=plzhi-1;i>=0;i--)
     46         if(loc>=mapin[i][1])
     47             return mapin[i][0];
     48     //return mapin[0][0];
     49 };
     50 //根据位置(用行和列表示),返回该位置像素处理后的结果
     51 int result(int row,int col)
     52 {
     53     int pix=locpix(row*width+col);int value=0;
     54     for(int i=row-1;i<=row+1;i++)
     55         for(int j=col-1;j<=col+1;j++)
     56         {
     57             if(i<0||i>=foot||j<0||j>=width||(i==row&&j==col))//边界
     58                 continue;
     59             if(abs(pix-locpix(i*width+j))>value)
     60                 value=abs(pix-locpix(i*width+j));
     61         }
     62     return value;
     63 };
     64 int cmp(pixInfo a,pixInfo b)
     65 {
     66     return a.loc<b.loc;
     67 }
     68 int main()
     69 {
     70     //ifstream in("test.txt");
     71     while(cin>>width&&width)
     72     {
     73         int pix,len;int k=0;
     74         sum=0;
     75         while(cin>>pix>>len&&len)    
     76         {    mapin[k][0]=pix;mapin[k][1]=sum;sum+=len;k++;    }
     77         plzhi=k;//pl对,连续段的数目
     78         mapin[plzhi][1]=sum;//输入数组的最后一个有效值
     79         foot=sum/width;//输入像素矩阵的行数
     80         int z=0;//记录输出数组mapout的长度
     81         for(int p=0;p<k;p++)//k为pl对数目
     82         {
     83             //pl对起始位置像素
     84             int row,col;//像素所处行和列
     85             row=mapin[p][1]/width;col=mapin[p][1]%width;
     86             //处理该像素及其相邻8个位置
     87             for(int i=row-1;i<=row+1;i++)
     88                 for(int j=col-1;j<=col+1;j++)
     89                 {
     90                     if(i<0||i>=foot||j<0||j>=width)//边界
     91                         continue;
     92                     mapout[z].pix=result(i,j);
     93                     mapout[z].loc=i*width+j+1;
     94                     z++;
     95                 }
     96             //如果当前连续段起始像素的位置不在每一行的开头,连续段又覆盖超过一行,处理下一行起始位置的像素
     97             if(col&&(col+1+mapin[p+1][1]-mapin[p][1])>width)//处理下一行开始的位置
     98             {
     99                 row=row+1;col=0;
    100                 //处理该像素及其相邻8个位置,共9个点
    101                 for(int i=row-1;i<=row+1;i++)
    102                     for(int j=col-1;j<=col+1;j++)
    103                     {
    104                         if(i<0||i>=foot||j<0||j>=width)//边界
    105                             continue;
    106                         mapout[z].pix=result(i,j);
    107                         mapout[z].loc=i*width+j+1;
    108                         z++;
    109                     }
    110             }    
    111         }
    112         sort(mapout,mapout+z,cmp);
    113         cout<<width<<endl;
    114         pixInfo fir=mapout[0];
    115         for(int m=0;m<z;m++)
    116         {
    117             if(fir.pix==mapout[m].pix)
    118                 continue;
    119             cout<<fir.pix<<' '<<mapout[m].loc-fir.loc<<endl;
    120             fir=mapout[m];
    121         }
    122         cout<<mapout[m-1].pix<<' '<<sum-fir.loc+1<<endl;
    123         cout<<'0'<<' '<<'0'<<endl;    
    124     }
    125     cout<<'0'<<endl;
    126     return 0;
    127 }
  • 相关阅读:
    sql 中 列转换成拼音首字母简写【邹建版】
    取一个任意数所有 和的等式
    sql 汉字转全拼音(非首字母)
    实现消息来时让网页标题闪动
    hdoj 1754 I Hate It 线段树(二)
    nyoj 247 虚拟城市之旅 路径压缩
    hdoj 1247 字典树分词 strncpy函数
    hdoj 1671字典树水题之三 静态数组节约内存法
    sort函数
    hdoj 1166 排兵布阵 线段树()
  • 原文地址:https://www.cnblogs.com/zhaopeng938/p/7570118.html
Copyright © 2011-2022 走看看