POJ 1009 Edge Detection
来源:互联网 发布:红警2 mac os10.12 编辑:程序博客网 时间:2024/05/16 18:12
Google面试受挫,听说以后找实习找工作都会考这样的题目,决定在百忙中一天至少写一道题,题目从poj百练上找。
Edge Detection是一道模拟类题目,但是如果逐个pixel进行计算,妥妥的TLE+MLE,思考半天无果,看了这篇博客以后明晰了思路,http://leons.im/posts/poj-1009-edge-detection-report/。
我们解决这道题的本质是寻找转换后的图片中,每一串value中的第一个值的位置,我们把这个点称为输出起始点,找到所有的可能的输出起始点就能得到输出的结果。
在上面的博客中,证明的一个核心定理在于,一个输出起始点的周围八个点中,一定至少有一个输入起始点。那么反过来,根据所有的输入起始点,可以找到所有可能的输出起始点,把这些所有的输出起始点找出来,处理一下就能得到输出结果。
具体的证明过程上面的博客写的很好,我这里再说一下细节上的问题:
1、要把height*width这个位置的点(也就是最后一个点的下一行的第一个点)作为输入起始点,不然的话左下角的这个点不符合上述定理;
2、在计算某个点和周围的点的最大距离的时候,考虑这个点的位置,即左边界还是右边界还是中间,而上下边界,反正在get_value()的时候也找不出相应的值,所以上下边界的情况其实不用考虑。
#include <iostream>#include <algorithm>#include <memory.h>#include <cmath>using namespace std;#define MAX_PAIRS 1005//用于记录有可能成为处理过后的图片的起始点的点 struct output_point{public: int value; int pos; bool operator< (output_point b){ if(this->pos < b.pos) return true; return false; }};output_point points[MAX_PAIRS*8];int output_count = 0;int width = 0;//用于记录输入数据 int pairs[MAX_PAIRS][2] = {0};//用于记录输出的结果 int ans[MAX_PAIRS][2] = {0};//给定一个pixel在所有pixel中的位置,返回这个pixel对应的值,如果越出图片外,则返回-1 int get_value(int pos, int pair_count){ if(pos <= 0){ return -1; } for(int i=0;i<pair_count;i++){ if(pos <= pairs[i][1]){ return pairs[i][0]; } else{ pos -= pairs[i][1]; } } return -1;}//给定一个pixel的中心点,计算这个点和周围的点的最大距离,并且记录到points数组中,成为待定的起始点 void cal_dis(int pos, int pair_count,int width){ int center = get_value(pos, pair_count); if(center == -1) return; //分成四种情况考虑,考虑这个点是在图片的左边缘,右边缘还是中间,另外考虑了width=1这种同时接触左右边缘的情况 int p[4][8] = {{0,0,0,-width,width,1,1-width,1+width}, {-1,-1+width,-1-width,-width,width,1,1+width,1-width}, {-1,-1+width,-1-width,-width,width,0,0,0}, {0,0,0,-width,width,0,0,0}}; int case_num = -1; if(width == 1) case_num = 3; else if(pos%width == 1) case_num = 0; else if(pos%width == 0) case_num = 2; else case_num = 1; //计算和周围点的距离的最大值 int max_dis = 0; for(int i=0;i<8;++i){ int t_pos = pos + p[case_num][i]; int t_dist = get_value(t_pos,pair_count); if(t_dist != -1){ t_dist = abs(t_dist - center); if(t_dist > max_dis) max_dis = t_dist; } } points[output_count].pos = pos; points[output_count].value = max_dis; output_count ++; return;}//给定一个输入数据的起始点,这个点周围的八个点都有可能成为输出数据的起始点 void cal_point(int pos, int pair_count,int width){ int p[9] = {-1,-1-width,-1+width,-width,width,1,1-width,1+width,0}; for(int i=0;i<9;++i){ cal_dis(pos+p[i], pair_count,width); } return;}int main(){ while(true){ scanf("%d",&width); if(width == 0) break; memset(pairs,0,sizeof(pairs)); memset(points,0,sizeof(points)); memset(ans,0,sizeof(ans)); output_count = 0; int pair_count = 0; int value, length; while(true){ scanf("%d%d",&value,&length); if(value == 0 && length == 0) break; pairs[pair_count][0] = value; pairs[pair_count][1] = length; pair_count += 1; } //找到所有的输入数据的起始点坐标 int current = 0; for(int i=0;i<pair_count;++i){ int start_point = current + 1; cal_point(start_point,pair_count,width); current += pairs[i][1]; } cal_point(current + 1,pair_count,width); sort(points,points + output_count); //根据所得到的起始点坐标,得到输出结果 int ans_count = 0; for(int i=0;i<output_count;++i){ if(i==0){ ans[ans_count][0] = points[0].value; ans[ans_count][1] = points[0].pos; ans_count ++; continue; } if(points[i].value != ans[ans_count-1][0]){ ans[ans_count-1][1] = points[i].pos - ans[ans_count-1][1]; ans[ans_count][0] = points[i].value; ans[ans_count][1] = points[i].pos; ans_count++; } } ans[ans_count-1][1] = current + 1 -ans[ans_count-1][1]; printf("%d\n",width); for(int i=0;i<ans_count;++i){ printf("%d %d\n",ans[i][0],ans[i][1]); } printf("0 0\n"); } printf("0\n"); return 0;}
阅读全文
0 0
- POJ 1009 Edge Detection
- poj 1009 Edge Detection
- poj 1009 Edge Detection
- POJ 1009 Edge Detection
- POJ-1009-Edge Detection
- [POJ][1009]Edge Detection
- POJ 1009: Edge Detection
- POJ 1009 Edge Detection
- POJ 1009--Edge Detection
- POJ 1009Edge Detection
- POJ 1009 Edge Detection
- POJ 1009--Edge Detection
- POJ 1009 Edge Detection
- poj 1009 Edge Detection (未完成)
- poj 1009 Edge Detection 模拟
- POJ 1009 Edge Detection 笔记
- POJ 1009 解题报告 Edge Detection
- POJ 1009 Edge Detection解题报告
- LUA 构造类
- Hibernate中的lazy(懒加载)属性
- 数据库事务隔离级别
- Hibernate的悲观锁和乐观锁
- hibernate中session的线程安全问题
- POJ 1009 Edge Detection
- [Design Pattern]Python设计模式——工厂方法
- 【Leetcode】【python】Longest Common Prefix
- 重温python基础7:字符串操作
- 人听3踢人3
- [Design Pattern]Python设计模式——设计原则
- [Design Pattern]Python设计模式——代理模式
- 快讯:北京大学领导班子出现新变化,混混儿不见了
- [Design Pattern]Python设计模式——模板模式