| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
这个是标程,不过要记得这里都是标准输入标准输出In Reply To:Re:求1009算法 Posted by:vxk at 2003-11-10 22:44:43 >
> 下面是我的师兄找到的代码,妈的,好难理解.
> #include <iostream.h>
> #include <fstream.h>
> #include <stdlib.h>
> const int MAXRUNS = 1000;
>
> // input data
> long imageWidth;
> long runLength[MAXRUNS + 2]; // runs with dummy border runs at ends
> int pixVal[MAXRUNS + 2]; // pixel values in runs.
> int lastRunIndex; // excluding final added border
> // dummy border runs at indices 0 and lastRunIndex+1 are added
>
> // data for position in grid
> // maintain positions in image of a pixel in the previous, current,
> // and next row with indices 0, 1, and 2 respectively in each array
> // runIndex and leftInRun
> // where an entry i in runIndex is used to reference the run given by
> // runLength[i] and pixVal[i] and the entries in leftInRun are the number
> // of pixels after the current pixel in its run.
> // Pixels may be in the dummy run before or after the image.
> // The pixel in the center row is in the center of the edge filter.
> int runIndex[3]; // index of run containing pixel
> long leftInRun[3]; // number of further pixels in the run
> long column; // column of pixel in center of filter, 0 to imageWidth - 1
> // only care about extreme values which mark edges
>
> int firstInRun(int r) {
> return (leftInRun[r] == runLength[runIndex[r]] - 1);
> }
>
> void advance(long nTot) {
> // advance the center pixel in preceding, current, and next rows
> // by n pixels as given by runIndex and leftInRun
> // and update the column
> column = (column + nTot) % imageWidth;
> for (int r = 0; r < 3; r++)
> for (long n = nTot; n > 0; )
> if (n <= leftInRun[r]) {
> leftInRun[r] -= n;
> n = 0;
> }
> else {
> n -= (leftInRun[r]+1);
> runIndex[r]++;
> leftInRun[r] = runLength[runIndex[r]]-1;
> }
> }
>
> int updateMax(int runI, int mid, int max) {
> int dif = pixVal[runI] - mid;
> if (dif < 0) dif = -dif;
> return (dif > max) ? dif : max;
> }
>
> int edgeFilter() {
> // calculate edge filter for the pixel in the middle row
> // This works for an image with any positive number of rows or columns
> int mid = pixVal[runIndex[1]]; // pixel value in mid row
> int max = 0;
> for (int r = 0; r < 3; r++) // for each row used in the filter
> if (runIndex[r] > 0 && runIndex[r] <= lastRunIndex) { // skip dummy rows
> max = updateMax(runIndex[r], mid, max); // use pixel value in row
> if (column > 0 && firstInRun(r)) // refer back to previous run if must
> max = updateMax(runIndex[r]-1, mid, max); // for pixel before
> if (column < imageWidth -1 && leftInRun[r] == 0) // see next run if must
> max = updateMax(runIndex[r]+1, mid, max); // for pixel after
> }
> return max;
> }
>
> long minRun() {
> // If for each of the current and previous and next row,
> // the pixel matches the pixel before and n > 0 pixels after, then
> // the edge filter value is the first of at least n that are the same.
> // Return the largest such n, or 1 if there is no such matchup
> // NOTE -- this does not give too large a number even
> // wrapping around an edge
> // It does not give the largest possible number always
> // -- it is reduced by nonmatches in pixels past borders.
> // The output buffer will assemble runs with the same
> // pixel value, so this is OK.
> long minAfter = 2000000000;
> for (int r = 0; r < 3; r++) {
> if (firstInRun(r)) return 1;
> if (minAfter > leftInRun[r]) minAfter = leftInRun[r];
> }
> if (minAfter == 0) return 1;
> return minAfter;
> }
>
> int main () {
> ifstream infile("edge.in");
> if (!infile) {
> cerr << "Can't open edge.in" << endl; exit(2);
> }
>
> ofstream outfile("edge.out");
> if (!outfile) {
> cerr << "Can't open edge.out" << endl; exit(2);
> }
>
> infile >> imageWidth;
> outfile << imageWidth << endl;
>
> while (imageWidth > 0) { // assume end sentinal is 0 image width
> // read, initialize image data
> runLength[0] = 2*imageWidth; // add initial border
> lastRunIndex = 0;
> do {
> lastRunIndex++;
> infile >> pixVal[lastRunIndex] >> runLength[lastRunIndex];
> } while (runLength[lastRunIndex] > 0); // assume dataset ends with 0 run length
> runLength[lastRunIndex] = 2*imageWidth; // add end border two lines wide
> lastRunIndex--; // border not counted in real run indices
>
> column = 0;
> // set up pixel to be filtered as first pixel in image in two steps:
> // simplest to place all pixels before first real row
> for (int r = 0; r < 3; r++) {
> runIndex[r] = 0; // dummy run index before actual image
> leftInRun[r] = (3-r)*imageWidth - 1;// pixels -3,-2,-1 rows into image
> }
> advance(2*imageWidth); // +2 rows to first pixels -1,0,1 rows into image
>
> // first time, initialize output buffer variables
> int outBufferPixVal = edgeFilter(); // apply filter
> long outBufferRun = minRun();// same filtered value for at least this int
> advance(outBufferRun); // skip past all the pixels calculated
> while (runIndex[1] <= lastRunIndex) {// while center before end of image
> int outPixVal = edgeFilter(); // same three steps as above
> long outRun = minRun(); // but with different
> advance(outRun); // run variables
> if (outPixVal == outBufferPixVal) // combine runs with equal values
> outBufferRun += outRun;
> else { // output old runLength, save new one
> outfile << outBufferPixVal << " " << outBufferRun << endl;
> outBufferPixVal = outPixVal;
> outBufferRun = outRun;
> }
> } // end of loop processing the input image
>
> // check input integrity -- integral number of rows
> if (column != 0) cout << " not multiple of width " << imageWidth << endl;
>
> outfile << outBufferPixVal << " " << outBufferRun << endl; // clear buffer
> outfile << 0 << " " << 0 << endl; // assume same sentinal format as input
> infile >> imageWidth;
> outfile << imageWidth << endl;
> } // end of all data sets
> return 0;
> }
>
Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator