POJ 1009

 
 
#include <stdio.h>
#include <math.h>
typedef struct SNode{
    unsigned char value;
    int len;
    struct SNode* p_next;
}SNode;

  
  
int width;
SNode sa_buf[6000];
int i_use_node;
SNode* sa_map[5000];
SNode* p_line_end;
SNode s_out;

  
  
int i_map_row;
int i_line_last_pos;
void fInit()
{
    i_use_node = 0;
    i_map_row = 1;

  
  
    sa_map[i_map_row++] = sa_buf+i_use_node++;
    sa_map[0] = sa_map[1];
    p_line_end = sa_map[0];
    i_line_last_pos = 0;
    s_out.len = 0;
}
void fAddNewLine()
{
    p_line_end->p_next = NULL;
    p_line_end = sa_buf+i_use_node++;
    sa_map[i_map_row++] = p_line_end;
    i_line_last_pos = 0;
}
void fAddSampLine(int value,
                  int i_span_line)
{
    p_line_end->len = width*i_span_line;
    p_line_end->value = value;
    fAddNewLine();
}
void fAdd(unsigned char value,int len)
{
    if(i_line_last_pos + len <= width)
    {
        p_line_end->value = value;
        p_line_end->len = len ;
        i_line_last_pos += len;
        if(i_line_last_pos == width)
        {
            fAddNewLine();
        }else
        {
            p_line_end->p_next = sa_buf+i_use_node++;
            p_line_end = p_line_end->p_next;

  
  
        }
        return ;
    }
    p_line_end->value = value;
    p_line_end->len = width - i_line_last_pos;
    len -= p_line_end->len;
    fAddNewLine();
    if(len <= width)
    {
        p_line_end->value = value;
        p_line_end->len = len;

  
  
        i_line_last_pos = len;
        if(len == width)
        {
            fAddNewLine();
        }else
        {
            p_line_end->p_next = sa_buf+i_use_node++;
            p_line_end = p_line_end->p_next;
        }
        return ;
    }
    fAddSampLine(value,1);
    len -= width;
    if(len < width)
    {
        fAdd(value,len);
        return;
    }else if(len < width*2)
    {
        fAddSampLine(value,1);
        fAdd(value,len - width);
        return;
    }
    fAddSampLine(value,len/width -1);
    fAdd(value,len%width + width);
}
int fGetMaxNumber(int* p)
{
    int i_max = 0;
    do
    {
        if(p[0] > i_max)
        {
            i_max = p[0];
        }
    }while((++p)[0] != -1);
    return i_max;
}
int fGetMinNumber(int* p)
{
    int i_min = p[0];
    do
    {
        if(p[0] < i_min)
        {
            i_min = p[0];
        }
    }while((++p)[0] != -1);
    return i_min;
}
void fShowNodeAndInit()
{
    if(s_out.len != 0)
    {
        printf("%d %d\n",s_out.value,s_out.len);
        s_out.len = 0;
        s_out.value = 0;
    }
}
void fAddOutNode(unsigned char value,int len)
{
    if((value|len) == 0)
    {//表示结束了
        fShowNodeAndInit();
        printf("0 0\n");
        return;
    }
    if(s_out.value !=value)
    {
        fShowNodeAndInit();
    }
    s_out.value = value;
    s_out.len += len;
}
typedef struct SImgLine{
    SNode* p_line;
    int i_line;
    unsigned char last_value;
    unsigned char next_value;
}SImgLine;
void fMoveToPix(SImgLine* p_line,int i_index)
{

  
  
    if(p_line->p_line->len + p_line->i_line < i_index)
    {
        p_line->last_value = p_line->p_line->value;
        p_line->i_line += p_line->p_line->len;
        p_line->p_line = p_line->p_line->p_next;
        p_line->next_value = p_line->p_line == NULL?p_line->last_value
                                                  :p_line->p_line->p_next == NULL?p_line->p_line->value
                                                                                :p_line->p_line->p_next->value;
    }
}
void fInitLine(SImgLine* p_line,SNode* p_node)
{
    p_line->p_line = p_node;
    p_line->i_line = 0;
    p_line->last_value = p_line->p_line->value;
    p_line->next_value = p_line->p_line == NULL?p_line->last_value
                                              :p_line->p_line->p_next == NULL?p_line->p_line->value
                                                                            :p_line->p_line->p_next->value;
}
/*
 * 计算第二行的值
*/
void fTrans(SNode* p_line1,
            SNode* p_line2,
            SNode* p_line3)
{
    SImgLine s_line[3];
    int i_index =1,i_next_index;
    fInitLine(s_line,p_line1);
    fInitLine(s_line+1,p_line2);
    fInitLine(s_line+2,p_line3);
    if (p_line2->len > width)
    {//表示这是色块
        fAddOutNode(0,p_line2->len);
        return;
    }

  
  
    while(i_index <= width)
    {

  
  
        fMoveToPix(s_line,i_index);
        fMoveToPix(s_line+1,i_index);
        fMoveToPix(s_line+2,i_index);

  
  
        //获取下一个需要计算的点
        i_next_index = i_index+1;

  
  
        if(i_next_index - s_line[0].i_line > 2
                &&i_next_index - s_line[2].i_line > 2)
        {
            int number[] = {s_line[0].p_line->len+s_line[0].i_line,
                            s_line[1].p_line->len+s_line[1].i_line,
                            s_line[2].p_line->len+s_line[2].i_line,
                            -1};
            int min = fGetMinNumber(number);
            if(i_next_index < min)
            {
                i_next_index = min;
            }
        }

  
  

  
  
        {
            unsigned char uc_pix_value = s_line[1].p_line->value;
            int number[] = {abs(s_line[0].p_line->value - uc_pix_value),
                            abs(s_line[2].p_line->value  - uc_pix_value),
                            s_line[0].i_line<i_index-1?0:abs(s_line[0].last_value - uc_pix_value),
                            s_line[1].i_line<i_index-1?0:abs(s_line[1].last_value - uc_pix_value),
                            s_line[2].i_line<i_index-1?0:abs(s_line[2].last_value - uc_pix_value),
                            s_line[0].i_line+s_line[0].p_line->len>i_index?0:abs(s_line[0].next_value - uc_pix_value),
                            s_line[1].i_line+s_line[1].p_line->len>i_index?0:abs(s_line[1].next_value - uc_pix_value),
                            s_line[2].i_line+s_line[2].p_line->len>i_index?0:abs(s_line[2].next_value - uc_pix_value),
                            -1};
            fAddOutNode(fGetMaxNumber(number),i_next_index - i_index);
        }
        i_index = i_next_index;
    }
}
void fShowMap()
{
    int i;
    for(i = 0 ;i < i_map_row;++i)
    {

  
  
        SNode* p_index=sa_map[i];
        printf("line %d :\n",i);
        while(p_index != NULL)
        {
            printf("value:%d,len:%d\n",p_index->value,p_index->len);
            p_index = p_index->p_next;
        }
    }
}

  
  
int main(void)
{
    int time = 0;
    while(scanf("%d",&width))
    {

  
  
        int value,len,i;
        ++time;

  
  
        if (width == 0)
        {
            break;
        }

  
  
        fInit();
        while(scanf("%d %d",&value,&len))
        {
            if(value == 0 && len ==0)
            {
                break;
            }
            fAdd(value,len);

  
  

  
  
        }
        --i_map_row;
        sa_map[i_map_row] = sa_map[i_map_row -1];
        //fShowMap();
        printf("%d\n",width);
        for(i = 1 ; i < i_map_row;++i)
        {
            fTrans(sa_map[i-1],sa_map[i],sa_map[i+1]);
        }
        fAddOutNode(0,0);
    }
    printf("0\n");
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值