POJ 1042 Source Code

#include<iostream>
#include<memory.h>

using namespace std;
const int MAX = 25;
void ComputeFish(int n, int h, int *f, int *d, int *t);

class Lake{
public:
	int fi; //Fish number at start 
	int di; //Decrese Rate
	int index; //Lake index;
	void Set(int fi, int di, int index);
	
};

bool CmpLake(Lake &a, Lake &b);
void SwapLake(Lake &a, Lake &b);

class Heap{
private:
	Lake *lakes;
	int size;
	void Adjust(int i);
public:
	Heap(Lake* a, int size); //We use size, not end index
	void BuildHeap();
	Lake GetMax(); //Heap will automatically decrese max.fi  by max.di
};

int main() {
	//get the input
	int n, h;
	int f[MAX], d[MAX], t[MAX - 1];
	do {
		cin>>n>>h;
		for(int i = 0 ; i < n; i++) cin>>f[i];
		for(int i = 0;  i < n; i++) cin>>d[i];
		for(int i = 0; i < n - 1; i++) cin>>t[i];
		//Compute
		if(n != 0) ComputeFish(n, h, f, d, t);
	}while(n != 0);
}

void ComputeFish(int n, int h, int *f, int *d, int *t) {
	//We must enumerate where to end
	Lake lakes[MAX];
	int bestNum, curNum;
	int bestPlan[MAX], curPlan[MAX];

	bestNum = -1;
	memset(bestPlan, 0, MAX * sizeof(int));

	for(int endLake = 0; endLake < n; endLake++) {
		//init
		curNum = 0; 
		memset(curPlan, 0, MAX * sizeof(int));
		//We end at endLake, ranges [0, n - 1]
		for(int i = 0; i <= endLake; i++) lakes[i].Set(f[i], d[i], i);
		
		//Use this to create a heap
		Heap a(lakes, endLake + 1);

		//Compute how many times we can fish
		int walktime = 0;
		for(int i = 0; i < endLake; i++) walktime += t[i] * 5;
		int fishtime = h * 60 - walktime;
		int times = fishtime / 5;
		
		for(int i = 0; i < times; i++) {
			Lake ret = a.GetMax();
			if(ret.fi == 0) {
				curPlan[ret.index] += times - i;//?
				break; 
			}
			curNum += ret.fi;
			curPlan[ret.index]++;
		}

		if(bestNum < curNum)  { //Do we need to consider bestNum == curNum??
			memcpy(bestPlan, curPlan, sizeof(int) * (endLake + 1)); 
			bestNum = curNum;
		}
	}
	for(int i = 0; i < n - 1; i++) cout<<(bestPlan[i] * 5)<<", ";
	cout<<bestPlan[n - 1] * 5<<endl;
	cout<<"Number of fish expected: "<<bestNum<<endl<<endl;
}

void Lake::Set(int fi, int di, int index) {
	this->fi = fi;
	this->di = di;
	this->index = index;
}

bool CmpLake(Lake &a, Lake &b) {
	return a.fi > b.fi || (a.fi == b.fi && a.index < b.index);
}

void SwapLake(Lake &a, Lake &b) { //I hope it works!
	Lake temp = b;
	b = a;
	a = temp;
}

void Heap::Adjust(int i) {
	int max = i;
	while(true) {
		int left = 2 * i + 1;
		int right = 2 * i + 2;

		if(left < size && CmpLake(lakes[left], lakes[max])) max = left;
		if(right < size && CmpLake(lakes[right], lakes[max])) max = right;
		if(max != i) {
			SwapLake(lakes[max], lakes[i]);
			i = max;
		}else break;
	}
}
void Heap::BuildHeap() {
	int median = (size - 2) / 2;
	for(int i = median; i >= 0; i--) Adjust(i);
}

Heap::Heap(Lake *a, int size) {
	this->lakes = a;
	this->size = size;
	BuildHeap();
}
Lake Heap::GetMax() {
	Lake ret = lakes[0];
	if(lakes[0].fi > lakes[0].di) lakes[0].fi -= lakes[0].di;
	else lakes[0].fi = 0;
	Adjust(0); //Forgetting this line will incur a serious error
	return ret;
}


这道题WA了3次:

1. 如果钓鱼钓到某个时间了, 那么每个湖都没有鱼的情形,应该呆在第一个湖;这段时间必须算进去

2. 考虑到 其实钓到的鱼的最小数目是0。 所以说bestNum一开始置为0是很愚蠢的做法。 应该置为-1.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值