Cod sursa(job #1494900)

Utilizator iordache.bogdanIordache Ioan-Bogdan iordache.bogdan Data 1 octombrie 2015 22:58:02
Problema Ferma Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.91 kb
#include <fstream>
#include <algorithm>
#include <cstring>
#include <vector>

#define DIM 20005
#define infile "ferma.in"
#define outfile "ferma.out"

std::ofstream fout(outfile);

//The Parser class can be used to optimize the reading of data from a specified path (or with little changes from the console)
class Parser {

private:

	char *buffer; //a string containing a contiguos array of chars from the input file, from this the numerical data would be extracted
	int maxLenBuffer; //the maximum length of the buffer
	int currentBufferIndex; //the current position in the buffer being processed

	std::fstream file; //the stream used to accesses the path

public:

	//no default constructor because the file path and the maxLenBuffer are relevant
	Parser(std::string path, int maxLenBuffer) {

		this->maxLenBuffer = maxLenBuffer;

		this->file.open(path, std::ios::in);

		buffer = new char[maxLenBuffer];

		//we read the first piece of data
		file.get(buffer, maxLenBuffer, EOF);

		//we set the cursor at position 0
		this->currentBufferIndex = 0;

	}

	//the Parser allows reading any integer numerical type: int, short, long long and their unsigned type
	template<class classType>
	void readNumber(classType &number) {

		number = 0;

		int sign = 1; //for positive/negative numbers;

		char prevChar = 0; //keeps the last processed char

		//skips unusable chars
		while (buffer[currentBufferIndex] < '0' || buffer[currentBufferIndex] > '9') {

			prevChar = buffer[currentBufferIndex];

			//next char
			++currentBufferIndex;

			//if the buffer ends we need to read again in case there is more data in the file
			if (currentBufferIndex == maxLenBuffer - 1) {

				file.get(buffer, maxLenBuffer, EOF);

				currentBufferIndex = 0;

			}

		}

		if (prevChar == '-')
			sign = -1;

		//here the number is built
		while (buffer[currentBufferIndex] >= '0' && buffer[currentBufferIndex] <= '9') {

			number = number * 10 + (buffer[currentBufferIndex] - '0');

			//next char
			++currentBufferIndex;

			//if the buffer ends we need to read again in case there is more data in the file
			if (currentBufferIndex == maxLenBuffer - 1) {

				file.get(buffer, maxLenBuffer, EOF);

				currentBufferIndex = 0;

			}

		}

		if (buffer[currentBufferIndex] == '.') {

			//next char
			++currentBufferIndex;

			//if the buffer ends we need to read again in case there is more data in the file
			if (currentBufferIndex == maxLenBuffer - 1) {

				file.get(buffer, maxLenBuffer, EOF);

				currentBufferIndex = 0;

			}

			classType fractionalExponent = 0.1; //with this we contruct the fractional part of the number

			while (buffer[currentBufferIndex] >= '0' && buffer[currentBufferIndex] <= '9') {

				number = number + fractionalExponent * (buffer[currentBufferIndex] - '0');

				fractionalExponent /= 10.0;

				//next char
				++currentBufferIndex;

				//if the buffer ends we need to read again in case there is more data in the file
				if (currentBufferIndex == maxLenBuffer - 1) {

					file.get(buffer, maxLenBuffer, EOF);

					currentBufferIndex = 0;

				}

			}

		}

		//puts the right sign to the number
		number *= sign;

	}

	//closes the file when an instance of this class is deleted
	~Parser() {

		file.close();

	}

};

const int inf = 2000000000;

int chickensProductivity[DIM];

int partialSum[DIM];

int deque[DIM];

int main() {

	Parser *parser = new Parser(infile, 3000000);

	int chickenCount, collectCount;

	parser->readNumber(chickenCount);
	parser->readNumber(collectCount);

	for (int chicken = 1; chicken <= chickenCount; ++chicken) {

		parser->readNumber(chickensProductivity[chicken]);

		chickensProductivity[chicken + chickenCount] = chickensProductivity[chicken];

	}


	int solution = 0;

	for (int collect = 1; collect <= collectCount; ++collect) {

		int left = 1, right = 1;

		deque[1] = 0;

		int currAns = -inf, leftEndAns, rightEndAns;

		for (int chicken = 1; chicken < 2 * chickenCount; ++chicken) {

			partialSum[chicken] = partialSum[chicken - 1] + chickensProductivity[chicken];

			if (left <= right && chicken - deque[left] == chickenCount) {

				++left;

			}


			if (partialSum[chicken] - partialSum[deque[left]] > currAns) {

				currAns = partialSum[chicken] - partialSum[deque[left]];

				leftEndAns = deque[left] + 1;

				rightEndAns = chicken;

			}

			while (left <= right && partialSum[chicken] <= partialSum[deque[right]]) {

				--right;

			}

			deque[++right] = chicken;

		}

		for (int chicken = leftEndAns; chicken <= rightEndAns; ++chicken) {

			int temp = (chicken <= chickenCount ? chicken : chicken - chickenCount);

			chickensProductivity[temp] *= -1;
			chickensProductivity[temp + chickenCount] *= -1;

		}

		solution += currAns;

	}


	fout << solution;

	return 0;

}

//Trust me, I'm the Doctor!