Edge Detection
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 22835   Accepted: 5398

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

 
分析:
英文的题目,有点蛋疼,有几个限制数字理解错了意思,浪费了时间。
注意点:
1. 计算点不是上下左右4个点,而是周围8个点。
2. 每个点与左侧delta是前一个点与右侧的delta,不需要重复计算。
3. 行可以很长很长,注意long。
4. 每组input可以长为1000,而不是256。
5. 处理采用输入一组处理一组,循环处理。
6. 需要采用快进处理:1)多行相同;2)同一行相同数字很多。(考虑了最简单场景)
 
 #include <stdio.h>
#include <stdlib.h>
#include <string.h> #define MAX_POINT_SERIES_NUM 1000 #define FAILURE (int)0xF
#define SUCCESS (int)0x0 #define TRUE (int)1
#define FALSE (int)0 #define MIN(a, b) (((a) < (b))?(a):(b))
#define MAX(a, b) (((a) > (b))?(a):(b)) typedef int BOOL; typedef struct
{
int value;
long long num;
long long startIdx;
long long endIdx;
}PointSeries; typedef struct
{
long long imageWide;
int pointsNum;
long long endIdx;
PointSeries points[MAX_POINT_SERIES_NUM];
}Image; Image g_input;
Image g_output; int GetInputImage(Image *input)
{
int i = ;
long long idx = ;
PointSeries *points = NULL; scanf("%I64d", &input->imageWide);
if( == input->imageWide)
{
printf("0\n");
return FAILURE;
} do
{
points = &input->points[i];
scanf("%d %I64d", &points->value, &points->num);
points->startIdx = idx;
points->endIdx = idx + points->num - ;
idx = idx + points->num;
i++;
}while(points->num != && MAX_POINT_SERIES_NUM <= i); input->endIdx = input->points[i-].endIdx; input->pointsNum = i;
return SUCCESS;
} void PrintImage(Image *image)
{
int i;
printf("%I64d\n", image->imageWide);
for(i = ; i < image->pointsNum; i++)
{
printf("%d %I64d\n",
image->points[i].value,
image->points[i].num);
}
if(image->imageWide != ) printf("0 0\n");
} static int GetLeftDelta(long long wide, PointSeries *points, long long idx, PointSeries *cmpPoints)
{
PointSeries *lastPoints = NULL;
long long lastIdx = idx - ; if(idx % wide !=
&& lastIdx >=
&& lastIdx < points->startIdx)
{
lastPoints = points-;
return abs(lastPoints->value - cmpPoints->value);
} return ;
} static int GetRightDelta(Image *input, PointSeries *points, long long idx, PointSeries *cmpPoints)
{
PointSeries *nextPoints = NULL;
long long nextIdx = idx + ; if(idx % input->imageWide != input->imageWide -
&& points->endIdx < input->endIdx
&& nextIdx > points->endIdx)
{
nextPoints = points+;
return abs(nextPoints->value - cmpPoints->value);
} return ;
} static int GetPointSeries(long long idx, long long endIdx, PointSeries **targetPoints)
{
PointSeries *points = (*targetPoints);
if(idx < || idx > endIdx) return FAILURE; while()
{
if(idx <= points->endIdx && points->startIdx <= idx) break; if(idx > points->endIdx)
{
points++;
}
else if(idx < points->startIdx)
{
points--;
}
} *targetPoints = points; return SUCCESS;
} static int GetOtherLineDelta(Image *input, PointSeries *orgPoints, long long idx)
{
int leftDelta, rightDelta, delta;
PointSeries *target = orgPoints; if(FAILURE == GetPointSeries(idx, input->endIdx, &target)) return ; leftDelta = GetLeftDelta(input->imageWide, target, idx, orgPoints);
rightDelta = GetRightDelta(input, target, idx, orgPoints);
delta = abs(target->value - orgPoints->value); delta = MAX(delta , leftDelta);
delta = MAX(delta , rightDelta); return delta;
} void SaveOutput(Image *output, int delta, long long num)
{
PointSeries *points = &output->points[output->pointsNum]; if(num == ) return; if(output->pointsNum == )
{
points->num = num;
points->value = delta;
output->pointsNum = ;
return;
} if((points-)->value != delta)
{
points->num = num;
points->value = delta;
output->pointsNum++;
}
else
{
(points-)->num += num;
}
} void ProcPoints(Image *input, PointSeries *points, long long num, int *rightDelta, long long *idx, Image *output)
{
long long j;
long long tmpIdx = *idx;
int leftDelta, upDelta, dowmDelta, delta;
int tmpRight = *rightDelta; for(j = ; j < num; j++)
{
leftDelta = tmpRight;
tmpRight = GetRightDelta(input, points, tmpIdx, points);
upDelta = GetOtherLineDelta(input, points, tmpIdx - input->imageWide);
dowmDelta = GetOtherLineDelta(input, points, tmpIdx + input->imageWide);
delta = MAX(leftDelta, tmpRight);
delta = MAX(delta, upDelta);
delta = MAX(delta, dowmDelta);
SaveOutput(output, delta, );
tmpIdx++;
}
*idx = tmpIdx;
*rightDelta = tmpRight;
} void RowFastForward(Image *input, PointSeries *points, int *rightDelta, long long *idx, Image *output)
{
long long firstNum, secondNum, thridNum;
long long endIdx;
long long wide = input->imageWide; if(*idx % wide == )
firstNum = wide;
else
firstNum = wide + ; ProcPoints(input, points, firstNum, rightDelta, idx, output); if(points->endIdx % wide == wide - )
endIdx = points->endIdx - wide;
else
endIdx = points->endIdx - wide - ; secondNum = endIdx + - points->startIdx - firstNum;
thridNum = points->endIdx - endIdx; SaveOutput(output, , secondNum);
*idx += secondNum; ProcPoints(input, points, thridNum, rightDelta, idx, output);
} inline BOOL CanBeRowFastForward(long long pointsNum, long long imageWide)
{
if(pointsNum >= * imageWide - )
{
return TRUE;
}
else
{
return FALSE;
}
} inline BOOL CanBeSpecFastForward(PointSeries *points, long long wide)
{
if(points->num ==
|| points->num / wide ==
|| points->num % wide !=
|| (points+)->num % wide != )
{
return FALSE;
}
return TRUE;
} void SpecFastForward(PointSeries *points, long long wide, int *specDelta, Image *output)
{
int tmpDeta = *specDelta;
long long num, lineNum = points->num / wide; num = (lineNum > ) ? wide : ; SaveOutput(output, tmpDeta, num); num = (lineNum > ) ? ((lineNum - )*wide) : ; SaveOutput(output, , num); if((points+)->num != && lineNum == )
{
tmpDeta = MAX(abs(points->value - (points+)->value), tmpDeta);
}
else if((points+)->num != && lineNum > )
{
tmpDeta = abs(points->value - (points+)->value);
}
else if((points+)->num == && lineNum > )
{
tmpDeta = ;
} SaveOutput(output, tmpDeta, wide); *specDelta = tmpDeta;
} void ProcImage(Image *input, Image *output)
{
long long i = , idx = ;
int rightDelta = ;
int specDelta = ;
PointSeries *points = &input->points[]; if(input->pointsNum == ) return; while(CanBeSpecFastForward(points, input->imageWide))
{
SpecFastForward(points, input->imageWide, &specDelta, output);
points++;
i++;
} for(; i < input->pointsNum; i++)
{
points = &input->points[i]; if(points->num <= ) continue; if(CanBeRowFastForward(points->num, input->imageWide))
{
RowFastForward(input, points, &rightDelta, &idx, output);
}
else
{
ProcPoints(input, points, points->num, &rightDelta, &idx, output);
}
}
} inline void InitOutputBuf(Image *input, Image *output)
{
output->pointsNum = ;
output->imageWide = input->imageWide;
} int main()
{
while(SUCCESS == GetInputImage(&g_input))
{
InitOutputBuf(&g_input, &g_output);
ProcImage(&g_input, &g_output);
PrintImage(&g_output);
} return ;
}

北大poj- 1009的更多相关文章

  1. 北大POJ题库使用指南

    原文地址:北大POJ题库使用指南 北大ACM题分类主流算法: 1.搜索 //回溯 2.DP(动态规划)//记忆化搜索 3.贪心 4.图论 //最短路径.最小生成树.网络流 5.数论 //组合数学(排列 ...

  2. 【Java】深深跪了,OJ题目Java与C运行效率对比(附带清华北大OJ内存计算的对比)

    看了园友的评论之后,我也好奇清橙OJ是怎么计算内存占用的.重新测试的情况附在原文后边. -------------------------------------- 这是切割线 ----------- ...

  3. POJ 1861 Network (Kruskal算法+输出的最小生成树里最长的边==最后加入生成树的边权 *【模板】)

    Network Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 14021   Accepted: 5484   Specia ...

  4. next_permutation 和 一个不成功的案例

    一个失败的案例:(POJ 1009) 题目描述 小翔同学的宿舍WIFI添加了密码,密码每天都会变更.而小翔每天都会给蹭网的同学们提供密码提示.现在请你根据密码提示,编写程序破译密码. 已知密码提示给出 ...

  5. 各大OJ

    北大POJ 杭电HDU 浙大ZOj 蓝桥杯 PAT

  6. leetcode学习笔记--开篇

    1 LeetCode是什么? LeetCode是一个在线的编程测试平台,国内也有类似的Online Judge平台.程序开发人员可以通过在线刷题,提高对于算法和数据结构的理解能力,夯实自己的编程基础. ...

  7. OJ题目JAVA与C运行效率对比

    [JAVA]深深跪了,OJ题目JAVA与C运行效率对比(附带清华北大OJ内存计算的对比) 看了园友的评论之后,我也好奇清橙OJ是怎么计算内存占用的.重新测试的情况附在原文后边. ----------- ...

  8. C++ 指针常见用法小结

    1. 概论 2.指针基础 3. 指针进阶 4. 一维数组的定义与初始化 5. 指针和数组 6. 指针运算 7. 多维数组和指针 8. 指针形参 9. 数组形参 10. 返回指针和数组 11. 结语   ...

  9. 几个比較好的IT站和开发库官网

    几个比較好的IT站和开发库官网 1.IT技术.项目类站点 (1)首推CodeProject,一个国外的IT站点,官网地址为:http://www.codeproject.com,这个站点为程序开发人员 ...

  10. C语言程序设计100例之(10):最大公约数

    例10        最大公约数 问题描述 有三个正整数a,b,c(0<a,b,c<10^6),其中c不等于b.若a和c的最大公约数为b,现已知a和b,求满足条件的最小的c. 输入数据 第 ...

随机推荐

  1. Activex、OLE、COM、OCX、DLL之间区别、联系[转]

    转自:http://baike.baidu.com/view/393671.htm 创建COM:http://blog.csdn.net/henry000/article/details/700839 ...

  2. Python方法和属性的动态绑定 --面向对象

    需要了解的: __ slots __:属于魔术变量,即:系统实现某些特定功能的变量 __ slots __: 1.限定类实例能添加的属性 2.对当前类起作用,对继承的子类是不起作用的 实操: # co ...

  3. 判断PDF文件是否相同(通过二进制流判断)

    一.Java代码 1.将PDF转为字节流    /*     * @step     *  1.使用BufferedInputStream和FileInputStream从File指定的文件中读取内容 ...

  4. struts1与struts2的区别。

    1) 两个框架都是MVC的WEB框架, 2) struts1是老牌框架,应用很广泛,有很好的群众基础,使用它开发风险很小,成本低,Struts2核心设计思想主要源自Webwork,实现更优雅,更容易扩 ...

  5. fflush 和 fsync 的区别

    int fflush(FILE *stream);If stream points to an output stream or an update stream in which the most ...

  6. .net实现网易云音乐下载

    客户端版的网易云音乐下载是需要vip的,网页版的虽然可以通过调试工具找到下载链接,但是用起来不是很方便,通过调试工具观察请求发现请求参数都是加密的,比如搜索歌曲的请求参数: 这个加密的实现肯定是写在j ...

  7. linux 7.2安装扩展redis

    unzip phpredis-php7.zip cd phpredis-php7 /usr/local/php7./bin/phpize ./configure --with-php-config=/ ...

  8. eclipse svn不显示提交人、提交时间的问题

    最近eclipse换到最新的mars版本,装了svn插件subversive后,拉下项目后发现都不显示提交人了,以前都不这样的呀,新版不一样了么? 后来网上搜索总算找到方法解决: Window--&g ...

  9. ImportError libcublas.so.9.0

    What to do when you've installed cuda and tensorflow, but you get this error right after you import ...

  10. Intellij Idea 解决字符乱码、设定颜色主题、字体

    1.写入字符编码设置 2.调整mintty 字体.主题