poj 2227 The Wedding Juicer

乱搞版:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define W 305
#define H 305
#define B 1000000001
#define STOP system("pause")
inline int max(int a, int b){	return a > b ? a : b; 	}
inline int min(int a, int b){	return a < b ? a : b; 	}

const int dir[][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0} };
int height[H][W], maps[H][W];
int w, h, maxb, ans;
void updata(int x, int y)
{
	if(x <= 0 || y <= 0 || x >= h-1 || y >= w-1)
		return;
	int tx, ty, temp;
	int minh = B;
	for(int i=0; i<4; i++)
	{
		tx = x + dir[i][0];
		ty = y + dir[i][1];
		minh = min(height[tx][ty], minh);
	}
	temp = max(minh, maps[x][y]);
	if(temp == height[x][y])
		return;
	if(temp < height[x][y])
	{
		ans -= height[x][y] - temp;
		height[x][y] = temp;
	}
			
	for(int i=0; i<4; i++)
	{
		tx = x + dir[i][0];
		tx = y + dir[i][1];
		if(height[tx][ty] > height[x][y])
		{	
			updata(tx, ty);
		}
	}
}
int main()
{
	while( scanf("%d %d", &w, &h) != EOF )
	{
		maxb = ans = 0;	
		for(int i=0; i<h; i++)
			for(int j=0; j<w; j++)
			{
				scanf("%d", &maps[i][j]);
				if(maps[i][j] > maxb)
					maxb = maps[i][j];
			}
		for(int i=0; i<h; i++)
			for(int j=0; j<w; j++)
				height[i][j] = maxb;	
		for(int i=0; i<h; i++)
		{
			height[i][0] = maps[i][0];
			height[i][w-1] = maps[i][w-1];
		}
		for(int i=0; i<w; i++)
		{
			height[0][i] = maps[0][i];
			height[h-1][i] = maps[h-1][i];
		}
		for(int i=0; i<h; i++)
			for(int j=0; j<w; j++)
				if(height[i][j] > maps[i][j])
					ans += height[i][j] - maps[i][j];
		int temp = -1;
		
		while(temp != ans)
		{
			temp = ans;
			for(int c=1; c < max(h, w)/2; c++)
			/*int c = 1;*/
			{
				for(int i=c; i<w-c; i++)
				{
					updata(  c, 	i  );	
					updata(  c,   w-i-1);
					updata(h-c-1,	i  );
					updata(h-c-1, w-i-1);
				}
				for(int i=c; i<h-c; i++)
				{
					updata(  i,	    c  );
					updata(h-i-1,   c  );
					updata(  i,	  w-c-1);
					updata(h-i-1, w-c-1);
				}
				/*
				for(int i=w-c-1; i>=c; i--)
				{
					updata(  c, 	i);	
					updata(h-c-1,	i);
				}
				for(int i=h-c-1; i>=c; i--)
				{
					updata(  i,	  c  );
					updata(  i,	w-c-1);
				}
				*/
			}	
		}
		/*
		for(int i=0; i<h; i++)
		{
			for(int j=0; j<w; j++)
				printf("%d ", height[i][j]);
			printf("\n");
		}
		*/
		printf("%d\n", ans);
	}
	return 0;
}

单调队列:

#include <cstdio>
#include <iostream>
#include <assert.h>
#include <cstring>
using namespace std;
class PQ
{
    public:
        PQ(bool (*callback)(void* a, void* b) = defaultCallback);
        bool insertKey(void* key);
        bool removeKey(void* key);
        bool isEmpty();
        void* topKey();
        void* popTopKey();
        void setCallback( bool (*callback)(void* a, void* b));
        void println(char* (*print)(void *));

    private:
        static const int HeapSize = 90005;
        static bool defaultCallback(void* a, void *b);

        int leftSon(int k);
        int rightSon(int k);
        int parent(int k);

        void heapify(int k);
        bool updataKey(int pos, void* newkey);

        int size;
        void* a[HeapSize];
        bool (*callback)(void* a, void* b);
};
PQ::PQ(bool (*_callback)(void* a, void* b))
{
    callback = _callback;
    size = 0;
}
bool PQ::isEmpty()
{
    return size == 0 ? true : false;
}

bool PQ::defaultCallback(void* a, void* b)
{
    return *(int*)a < *(int*)b;
}
inline int PQ::leftSon(int k)	{	return k<<1;	}
inline int PQ::rightSon(int k)	{	return (k<<1)+1;}
inline int PQ::parent(int k)	{	return k>>1;	}
void PQ::heapify(int k)
{
    while(true)
    {
        int l = leftSon(k);
        int r = rightSon(k);
        int m = k;
        if(l <= size && callback(a[l], a[m]) ) m = l;
        if(r <= size && callback(a[r], a[m]) ) m = r;
        if(m == k)	return;
        swap(a[m], a[k]);
        //printf("~ swap %d %d\n", m, k);
        //heapify(m);
        k = m;
    }
}
bool PQ::insertKey(void *key)
{
    size++;
    updataKey(size, key);
    return true;
}
bool PQ::updataKey(int pos, void *newkey)
{
    a[pos] = newkey;
    //cout << "~ " << pos << " " << *(int*)newkey << endl;
    heapify(pos);
    while(pos > 1 && callback(a[pos], a[ parent(pos) ]) )
    {
        swap(a[pos], a[ parent(pos) ]);
        pos = parent(pos);
    }
    return true;
}
void* PQ::topKey()
{
    return a[1];
}
void* PQ::popTopKey()
{
    assert(size != 0);
    void* v = a[1];
    swap(a[1], a[size]);
    size--;
    heapify(1);
    return v;
}
bool PQ::removeKey(void *key)
{
    //TODO!
    assert(size != 0);
    return false;
}
void PQ::println(char* (*print)(void *))
{
    for(int i=1; i<=size; i++)
        printf(" ~%3d: %s\n", i, print(a[i]));
//    printf("\n");
}
class Point
{
public:
    int w, h, b, B;
    bool v;
    void init(int w, int h)
    {
        this->v = false;
        this->w = w;
        this->h = h;
        this->B = 110000000;
    }
};
char* printPoint(void* a)
{
    static char s[100];
    sprintf(s, "(%d, %d : %d)", ((Point*)a)->h, ((Point*)a)->w, ((Point*)a)->b);
    //printf("(%d, %d)", ((Point*)a)->h, ((Point*)a)->w);
    return s;
}
bool callback(void *a, void *b)
{
    return ((Point*)a)->B < ((Point*)b)->B ;
}

#define W 305
#define H 305
int w, h;
Point maze[H][W];
static const int dxdy[][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0} };
bool checkPoint(int tw, int th)
{
    if(tw < 1 || tw > w-2)  return false;
    if(th < 1 || th > h-2)  return false;
    if(maze[th][tw].v == true)  return false;
    return true;
}
int main()
{
    while( scanf("%d%d", &w, &h) != EOF)
    {
        for(int i=0; i<h; i++)
            for(int j=0; j<w; j++)
            {
                scanf("%d", &maze[i][j].b);
                maze[i][j].init(j, i);
            }
        PQ p(callback);
        for(int i=1; i<h-1; i++)
        {
            maze[i][0].v =
            maze[i][w-1].v = true;

            maze[i][0].B = maze[i][0].b;
            maze[i][w-1].B = maze[i][w-1].b;

            p.insertKey(&maze[i][0]);
            p.insertKey(&maze[i][w-1]);
        }
        for(int i=1; i<w-1; i++)
        {
            maze[0][i].v =
            maze[h-1][i].v = true;

            maze[0][i].B = maze[0][i].b;
            maze[h-1][i].B = maze[h-1][i].b;

            p.insertKey(&maze[0][i]);
            p.insertKey(&maze[h-1][i]);

        }
        //p.println(printPoint);
        while( p.isEmpty() == false)
        {
            Point top = *(Point*)p.topKey();
            //printf("top key is (%d %d) %d %d\n", top.h, top.w, top.b, top.B);
            for(int i=0; i<4; i++)
            {
                int w = top.w+dxdy[i][0];
                int h = top.h+dxdy[i][1];
                if(checkPoint(w, h))
                {
                    if(maze[h][w].B == maze[h][w].b)    continue;
                    if(maze[h][w].B > top.B )
                    {
                        if(maze[h][w].b <= top.B)   maze[h][w].B = top.B;
                        else                        maze[h][w].B = maze[h][w].b;
                        p.insertKey(&maze[h][w]);
                        maze[h][w].v = true;
                    }
                }
            }
            //printMaze();
            p.popTopKey();
            top.v = false;
        }
        int ans = 0;
        for(int i=1; i<h-1; i++)
            for(int j=1; j<w-1; j++)
            {
                ans += maze[i][j].B - maze[i][j].b;
            }
        cout << ans << endl;
    }
    return 0;
}


单调队列stl:

#include <cstdio>
#include <iostream>
#include <assert.h>
#include <cstring>
#include <queue>
using namespace std;
class Point
{
public:
    int w, h, b, B;
    bool v;
    void init(int w, int h)
    {
        this->v = false;
        this->w = w;
        this->h = h;
        this->B = 110000000;
    }
};
struct Cmp
{
    bool operator()(Point* a, Point* b)
    {
        return a->B > b->B;
    }
};
#define W 305
#define H 305
int w, h;
Point maze[H][W];
static const int dxdy[][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0} };
inline bool checkPoint(int tw, int th)
{
    if(tw < 1 || tw > w-2)  return false;
    if(th < 1 || th > h-2)  return false;
    if(maze[th][tw].v == true)  return false;
    return true;
}
int main()
{
    while( scanf("%d%d", &w, &h) != EOF)
    {
        for(int i=0; i<h; i++)
            for(int j=0; j<w; j++)
            {
                scanf("%d", &maze[i][j].b);
                maze[i][j].init(j, i);
            }
        priority_queue<Point*, vector<Point*>, Cmp> pq;
        for(int i=1; i<h-1; i++)
        {
            maze[i][0].v =
            maze[i][w-1].v = true;
            maze[i][0].B = maze[i][0].b;
            maze[i][w-1].B = maze[i][w-1].b;
            pq.push(&maze[i][0]);
            pq.push(&maze[i][w-1]);
        }
        for(int i=1; i<w-1; i++)
        {
            maze[0][i].v =
            maze[h-1][i].v = true;
            maze[0][i].B = maze[0][i].b;
            maze[h-1][i].B = maze[h-1][i].b;
            pq.push(&maze[0][i]);
            pq.push(&maze[h-1][i]);
        }
        while( pq.empty() == false )
        {
            Point top = *(Point*)pq.top();
            for(int i=0; i<4; i++)
            {
                int w = top.w+dxdy[i][0];
                int h = top.h+dxdy[i][1];
                if(checkPoint(w, h))
                {
                    if(maze[h][w].B == maze[h][w].b)    continue;
                    if(maze[h][w].B > top.B )
                    {
                        if(maze[h][w].b <= top.B)   maze[h][w].B = top.B;
                        else                        maze[h][w].B = maze[h][w].b;

                        pq.push(&maze[h][w]);
                        maze[h][w].v = true;
                    }
                }
            }
            pq.pop();
            top.v = false;
        }
        int ans = 0;
        for(int i=1; i<h-1; i++)
            for(int j=1; j<w-1; j++)
            {
                ans += maze[i][j].B - maze[i][j].b;
            }
        cout << ans << endl;
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值