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. Failed to find configured root that contains

    这个主要问题是在android系统下7.0 拍照时,Android提供FileProvider类来供应用之间共享数据. 出现这个问题多为xml文件 path 类型和代码中调用的类型不同导致的 以下为多 ...

  2. idea中xml打开方式变成file,代码变成灰色

    耗费了很久啊.... 新建文件的时候没有输入后缀.xml.自此无论复制修改还是新建都是文件的格式,其他名字倒是可以,但是我不能修改名字. 解决办法: OK了:

  3. 图融合之加载子图:Tensorflow.contrib.slim与tf.train.Saver之坑

    import tensorflow as tf import tensorflow.contrib.slim as slim import rawpy import numpy as np impor ...

  4. C语言实现过滤ASCII在0~127范围内的字符,并去除重复的字符

    #include <stdio.h> #include <string.h> /* 1.以字符串作为参数 2.找出ASCII在1~127范围内的字符 3.去掉重复字符 */ i ...

  5. vscode相关配置

    一.插件 二.首先项设置: { "git.enableSmartCommit": true, "gitlens.advanced.messages": { &q ...

  6. mac下idea搭建maven项目的一些问题总结

    1.关于版本 目标原版与原发行版本不一致 <build> <finalName>comment</finalName> <plugins> <pl ...

  7. 搭建SDN网络——mininet

    好久没来写不博客,感觉自己不写写博客,就完全想不起当天干了什么.前几天参加了小米的面试,整个人被打击的不行,还是要好好学习,不然工作都找不到. 这学期选了SDN的课,只有六周,学完有点懵,这这这等于什 ...

  8. javascript 中的number

    大家都知道javascript中有五种简单数据类型,number,string,boolean,null,undefined,复杂数据类型是object.本文主要记录下number类型的一些可能不太常 ...

  9. 简单Socket网络通信

    问题:编写一个网络应用程序,有客户端和服务端,客户端向服务端发送一个字符串(如"Hello Socket"),服务器收到该 字符串后将其打印到命令行上,然后向客户端返回该字符串的长 ...

  10. centos 日志文件

    以下介绍的是20个位于/var/log/ 目录之下的日志文件.其中一些只有特定版本采用,如dpkg.log只能在基于Debian的系统中看到./var/log/messages — 包括整体系统信息, ...