poj1009

这是一道有挺难的题目。英语硬伤。好吧,我承认我在百度上找了翻译。
题目大体意思我就不说了,百度有翻译。。
这道题目一开始我是没有任何头绪的,因为,直接对像素点暴力的话肯定TLE。。开二维数组然后MLE的弱智想法我肯定不会去想。。所以,主要是对时间复杂度的优化。
感谢 这个博客的代码给了我很大的启发。
解题思路如下:
根据题目给出的条件——pair最多只有1000对,然后仔细思考会发现,如果只对像素发生变化的地方进行计算——也就是题目里说的编码了。
这个的证明我找了好久没找到,一些博客里给出的证明链接已经失效了。
但是这样是可行的,我也不知道为什么可行,找不到证明。。不过即使是知道了算法,我还是在写代码的过程中出现了问题。某个地方少写了一个等于号,然后WA了两次。其实这样的——我们需要对最后一个点进行编码。。因为,。。因为我也不知道为什么(不过这里似乎给粗了解释)。
然后我把某组数据用excel画粗来了。。嗯,excel对这道题目来说是一个很好的辅助工具。
看一组数据吧
30
0 10
10 62
5 20
15 62
5 20
25 6
5 15
0 9
25 6
0 0
用excel画出来是这样的
这里写图片描述
其中需要编码的点我用金黄色的标记了粗来,确定编码位置的点橘黄色的标记了,编码完之后是这样的
这里写图片描述
这里要尤其注意,最后的最后,一定要在最后进行一次编码,也就是其实已经超出长度的那个地方。。但是就是一定要在那个excel表第8行和第15行的那里编码一次。。不然就会有bug。体现到代码里面就是 进行跳跃的标记变量p要做到等于pairnum的地方。。实际上有数字的地方只是0~pairnum-1。。for(p = 0; p <= pairnum; ++p)。。我就是少写了那个等号。。然后WA两次。
下面是我的代码:

#include <cstdio>
#include <algorithm>
#define MAX_PAIR 1111
#define abs(a) ((a)>0?(a):(-a))
#define max(a,b) ((a)>(b)?(a):(b))

typedef struct outmappix{
    int pos, code;
} pix;

int width, totlen;
int pixmap[MAX_PAIR][2];
pix outmap[MAX_PAIR*8];

int  getval(int pos);
int  getcod(int pos);
void swap(pix* a, pix* b);
int  cmp(const void* a, const void * b);

int main(int argc, char const *argv[])
{
    while(scanf("%d", &width) != EOF && width != 0){
        int pixval, pixlen;
        int inpairnum = totlen = 0;
        while(scanf("%d%d", &pixval, &pixlen) && (pixlen || pixval)) {
            pixmap[inpairnum][0] = pixval;
            pixmap[inpairnum][1] = pixlen;
            totlen += pixlen;
            inpairnum ++;
        }
        int outpairnum = 0, curpos = 0;
        for (int p = 0; p <= inpairnum; ++p){
            int row = curpos/width;
            int col = curpos%width;
            for (int i = row-1; i <= row+1; ++i){
                for (int j = col-1; j <= col+1; ++j){
                    int tmppos = i*width+j;
                    if(i<0 || j<0 || j>=width || tmppos >= totlen){
                        continue;
                    }
                    outmap[outpairnum].pos  = tmppos;
                    outmap[outpairnum].code = getcod(tmppos);
                    outpairnum ++;
                }
            }
            curpos += pixmap[p][1];
        }
        qsort(outmap, outpairnum, sizeof(pix), cmp);
        printf("%d\n", width);
        pix tmp = outmap[0];
        for (int i = 0; i < outpairnum; ++i){
            if(tmp.code == outmap[i].code){
                continue;
            }
            printf("%d %d\n", tmp.code, outmap[i].pos-tmp.pos);
            tmp = outmap[i];
        }
        printf("%d %d\n", tmp.code, totlen-tmp.pos);
        printf("0 0\n");
    }
    printf("0");
    return 0;
}

int getval(int pos)
{
    int p = 0;
    for(int i = 0; i <= pos; i += pixmap[p++][1]);
    return pixmap[p-1][0];
}

int getcod(int curpos)
{
    int ans = 0;
    int val = getval(curpos);
    int row = curpos / width;
    int col = curpos % width;
    for (int i = row-1; i <= row+1; ++i){
        for(int j = col-1; j <= col+1; ++j){
            int tmppos = i*width+j;
            if(i<0 || j<0 || j>=width || tmppos >= totlen){
                continue;
            }
            int tmpval = getval(tmppos)-val;
            tmpval = abs(tmpval);
            ans = max(ans, tmpval);
        }
    }
    return ans;
}

int cmp(const void* a, const void* b)
{
    pix* x = (pix*)a;
    pix* y = (pix*)b;
    return x->pos - y->pos;
}

然后不得不提出来的是,从这个题目里面学会了用STL里面的qsort函数。。。竟然用了函数指针回调函数。so。又是一次不错的学习。再次感谢这个博客

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值