POJ 1009

/*
 * poj_1009.c
 * accepted!
 * refers to http://liangsun.org/posts/poj-1009-edge-detection-report/
 */
#include <stdio.h>
#include <stdlib.h> /* qsort () */
#include <math.h> /* abs () */

#ifdef DEBUG 
    #define SZL_DEBUG(fmt, args...) printf("%s:%d:"fmt"\n",__FILE__,__LINE__, ##args)
#else 
    #define SZL_DEBUG(fmt, args...) 
#endif 

#define MAX(a,b) ((a)>(b)?(a):(b))

#define N (1024)

typedef struct _out_node{
    int value;
    int location;
}OutNode;

int cmp (const void * e1, const void * e2);
static int get_value (int (* in_data)[2], int pairs_num, int p);
static int encode (int p_to_encode, int (* in_data)[2], int width, int pairs_num, int location);
static void solve (int (* in_data)[2], int width, int pairs_num, int location);

FILE * outfile;

void main (void){
    int in_data[N][2];
    int width;
    int value, rle;
    int in_pairs_num, location;
    int i;
    outfile = stdout;   
#ifdef DEBUG
    outfile = fopen ("output.txt", "w+");
#endif
    while (EOF != scanf ("%d", &width)){
        if (0 == width ){
            break;
        }
        location = 0;
        i = 0;
        scanf ("%d %d\n", &value, &rle);     
        while (0 != rle){
            in_data[i][0] = value;
            in_data[i][1] = location;
            location += rle;
            i++;
            scanf ("%d %d\n", &value, &rle);
        }
        in_pairs_num = i;
        fprintf (outfile, "%d\n", width);
        solve (in_data, width, in_pairs_num, location);
        fprintf (outfile, "0 0\n");
    }
    fprintf (outfile, "0\n");
    fclose (outfile);
}

static void solve (int (*in_data)[2], int width, int pairs_num, int location){
    OutNode out_data[N*9];
    int i,j,k;
    int row, col;
    int p;

    int out_num = 0;
    for (i=0; i<pairs_num; i++){
#ifdef DEBUG
           SZL_DEBUG ("\nADDRESSING NODE %d\n", in_data[i][0]);
#endif
       row = in_data[i][1] / width;
       col = in_data[i][1] % width;
       for (j=row-1; j<=row+1; j++){
           for (k=col-1; k<=col+1; k++){
               p = j*width+k;
               if (j<0 || p<0 || p>=location){
                   continue;
               }
#ifdef DEBUG
           SZL_DEBUG ("\nbefore encode ()");
#endif
               out_data[out_num].value = encode (p, in_data, width, pairs_num, location);
#ifdef DEBUG
           SZL_DEBUG ("after encode ()\n");
#endif
               out_data[out_num].location = p;
               out_num++;
           }
       }
    }
    /*  at the last position */
    row = location / width;
    col = location % width;
    for (j=row-1; j<=row+1; j++){
       for (k=col-1; k<=col+1; k++){
           p = j * width + k;
           if (p<0 || p>=location || j<0 ){
                continue;
           }
           out_data[out_num].value = encode (p, in_data, width, pairs_num, location);
           out_data[out_num].location = p;
           out_num ++;
       }
    }
    
    qsort (out_data, out_num, sizeof (OutNode), cmp);
    OutNode out_curr = out_data[0];
    for (i=0; i<out_num; i++){
          if (out_curr.value == out_data[i].value){
              continue;
          }
          fprintf (outfile, "%d %d\n", out_curr.value, out_data[i].location - out_curr.location);
          out_curr = out_data[i];
    }
    fprintf (outfile, "%d %d\n", out_curr.value, location - out_curr.location);
}

static int encode (int p_to_encode, int (* in_data)[2], int width, int pairs_num, int location){
   int ret = 0;
   int row,col;
   int i,j;
   int p;
   int t, t1, t2;
   row = p_to_encode / width;
   col = p_to_encode % width;
   for (i=row-1;i<=row+1;i++){
       for (j=col-1;j<=col+1;j++){
           p = i * width + j;
           if (i<0 || p<0 || p >= location || j<0 || j>=width){
              continue;
           }  
           t1 = get_value(in_data, pairs_num, p_to_encode);
           t2 = get_value(in_data, pairs_num, p);
           t = abs (t1-t2);
#ifdef DEBUG
           SZL_DEBUG ("(%d,%d,%d)=%d, (%d,%d,%d)=%d, t=%d", row, col, p_to_encode, t1, p/width, p%width, p, t2, t);
#endif
           ret = MAX (ret, t);
       }
   }
   return (ret);
}

static int get_value (int (* in_data)[2], int pairs_num, int p){
   int left=0, right = pairs_num-1;
   int mid;
   while (left <= right){
       mid = ( left + right ) / 2;
       if (p >= in_data[mid][1]){
           left = mid + 1;
       }
       else{
           right = mid - 1;
       }
   }
   return in_data[right][0];
}

int cmp (const void * e1, const void * e2){
    return ((OutNode *)e1)->location - ((OutNode *)e2)->location;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值