POJ-1009-Edge Detection

来源:互联网 发布:免root修改数据 编辑:程序博客网 时间:2024/05/17 02:17
// Input: imageNum * IMAGE{ width, PAIRS{ pixel, length} }//10000-2551-10^9// Output: max(pixel, pixelNear)// Method: get enough lines to calc current line#include <stdio.h>#include <math.h>#include <time.h>typedef unsigned char BYTE;// STRUCTS// pairs infostruct SPAIR{BYTE pixel;int length;int index;SPAIR *next;};// image infostruct SIMAGE{int width;int totalLen;SPAIR *pairs;int curRow;int first;int over;int isHead;int isTail;int count;};// output infostruct SOUTPUT{BYTE pixel;int len;};// time infostruct STIMEINFO{float getPixel;float calcOutputPixel;float handleEasyRow;float handleImageRow;float handleImage;float imageTime[1500];};// VARS// current imageSIMAGE curImage;SOUTPUT curOutput;STIMEINFO curTime;// read enough pixelsvoid readEnoughPixels(int destLen){if (curImage.totalLen >= destLen || curImage.over == 1)return;// read enoughwhile (curImage.totalLen < destLen){SPAIR *pair = new SPAIR;scanf("%u %d", &pair->pixel, &pair->length);// end flagif (pair->pixel == 0 && pair->length == 0){curImage.over = 1;// set tailcurImage.isTail = 1;delete pair;return;}pair->index = curImage.totalLen;// add to pairs headpair->next = curImage.pairs;curImage.pairs = pair;curImage.totalLen += pair->length;}}// getPixel by row, colbool getPixel(BYTE &pixel, int row, int col){clock_t start = clock();// check row and colif (row < 0 || col < 0 || col >= curImage.width)return false;int index = row * curImage.width + col;// get enough pixelsreadEnoughPixels(index + 1);if (index > curImage.totalLen-1 && curImage.over == 1)return false;// look through image's pairs to get the pixelSPAIR *pos = curImage.pairs;while (pos && pos->index > index)pos = pos->next;// first time must clear the no-used pairsif (curImage.first){curImage.first = 0;// find no-used pairsSPAIR *found = pos->next;SPAIR *before = pos;while (found){if (found->index + found->length + curImage.width < index)break;before = found;found = found->next;}if (found){SPAIR *temp;while (found){temp = found;found = found->next;delete temp;}before->next = 0;}}clock_t end = clock();curTime.getPixel += (float)(end - start) / CLOCKS_PER_SEC;if (pos){pixel = pos->pixel;return true;}elsereturn false;}// output current pixelvoid outputCurPixel(){printf("%d %d\n", curOutput.pixel, curOutput.len);}// output zero rowsvoid outputZeroRows(int rowNum){// output the pixelif (!curOutput.len){curOutput.pixel = 0;curOutput.len = curImage.width * rowNum;}else{if (!curOutput.pixel){curOutput.len += curImage.width * rowNum;}else{// output currentoutputCurPixel();curOutput.pixel = 0;curOutput.len = curImage.width * rowNum;}}}// get current pair by rowSPAIR* getCurPair(int row){if (row < 0 || (curImage.over == 1 && curImage.totalLen-1 < row * curImage.width))return 0;// get enough rowsif (row * curImage.width > curImage.totalLen-1)readEnoughPixels(row * curImage.width + 1);// find the pairSPAIR *pos = curImage.pairs;while (pos && pos->index > row * curImage.width)pos = pos->next;return pos;}// calc the output pixel : get the max distint offset[][2] = {-1, -1,0,-1,1,-1,-1, 0,1, 0,-1, 1,0, 1,1, 1};bool calcOutputPixel(int row, int col){BYTE pixel, pixelNear;clock_t start = clock();// check if is head and tailif (curImage.isHead && curImage.isTail){SPAIR *cur = getCurPair(curImage.curRow);if (cur && cur->length == curImage.width){curOutput.pixel = 0;curOutput.len = curImage.width;return false;}}if (!getPixel(pixel, row, col))return false;// calc the near pixels' distint dist = -1;int temp;for (int i = 0; i < 8; ++i){// head rows jump to 3if (curImage.isHead && i < 3)i = 3;// tail rows jump outelse if (curImage.isTail && i == 5)break;if (getPixel(pixelNear, row + offset[i][1], col + offset[i][0])){temp = (int)abs((int)pixel - (int)pixelNear);if (temp > dist)dist = temp;}}// output the pixelif (!curOutput.len){curOutput.pixel = dist;curOutput.len = 1;}else{if (curOutput.pixel == dist){++ curOutput.len;}else{// output currentoutputCurPixel();curOutput.pixel = dist;curOutput.len = 1;}}clock_t end = clock();curTime.calcOutputPixel += (float)(end - start) / CLOCKS_PER_SEC;return true;}// handle easy image rowsint handleEasyRows(){clock_t start = clock();if (!curImage.isHead){SPAIR *prev = getCurPair(curImage.curRow - 1);if (prev){int colStart = (curImage.curRow-1) * curImage.width - prev->index;// cur 3 rows are the sameint rowCount = (prev->length - colStart) / curImage.width;if (rowCount < 3)return 0;if (curImage.isHead)curImage.isHead = 0;int rowAdd = rowCount - 2;curImage.curRow += rowAdd;outputZeroRows(rowAdd);return 0;}}else{SPAIR *cur = getCurPair(curImage.curRow);if (cur){// cur 3 rows are the sameint rowCount = cur->length / curImage.width;if (rowCount < 3)return 0;if (curImage.isHead)curImage.isHead = 0;int rowAdd = rowCount - 2;curImage.curRow += rowAdd;outputZeroRows(rowAdd);return 0;}}clock_t end = clock();curTime.handleEasyRow += (float)(end - start) / CLOCKS_PER_SEC;return 0;}// handle image rowint handleImageRow(){clock_t start = clock();// clear easy rowswhile (handleEasyRows()) ;curImage.first = 1;// go through the rowfor (int i = 0; i < curImage.width; ++i){// calc the output pixelif (!calcOutputPixel(curImage.curRow, i)){if (curOutput.len > 0)outputCurPixel();return 0;}}curImage.curRow ++;if (curImage.isHead)curImage.isHead = 0;clock_t end = clock();curTime.handleImageRow += (float)(end - start) / CLOCKS_PER_SEC;return 1;}// handle imagevoid handleImage(){clock_t start = clock();// reset last imagecurImage.totalLen = 0;curImage.curRow = 0;curImage.first = 1;curImage.over = 0;curImage.isHead = 1;curImage.isTail = 0;curOutput.len = 0;curImage.count ++;SPAIR *temp;while (curImage.pairs){temp = curImage.pairs;curImage.pairs = curImage.pairs->next;delete temp;}curImage.pairs = 0;// handle each rowwhile (handleImageRow()) ;clock_t end = clock();float runTime = (float)(end - start) / CLOCKS_PER_SEC;curTime.imageTime[curImage.count - 1] = runTime;curTime.handleImage += runTime;}#define LOCALint main(){#ifdef LOCAL freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);#endif// get image widthcurImage.pairs = 0;scanf("%d", &curImage.width);while (curImage.width){printf("%d\n", curImage.width);handleImage();printf("0 0\n");scanf("%d", &curImage.width);}printf("0\n");#ifdef LOCALprintf("getPixel:%f\n", curTime.getPixel);printf("calcOutput:%f\n", curTime.calcOutputPixel);printf("handleEasy:%f\n", curTime.handleEasyRow);printf("handleRow:%f\n", curTime.handleImageRow);printf("handleImage:%f\n\n", curTime.handleImage);for (int i = 0; i < curImage.count; i++){printf("image %d: %f\n", i, curTime.imageTime[i]);}#endifreturn 0;}

原创粉丝点击