Pagini recente » Cod sursa (job #399145) | Cod sursa (job #2064641) | Cod sursa (job #1938497) | Cod sursa (job #2712942) | Cod sursa (job #1494900)
#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!