EDIT : - , ; , . , , , , . , , , .
. , , , , .
pieces.txt
1
15 8 3
3 8
11 2
8 6
DefenderBoard.h
#ifndef DEFENDER_BOARD_H
#define DEFENDER_BOARD_H
#include <fstream>
#include <vector>
#include <algorithm>
struct Coord {
unsigned x;
unsigned y;
Coord() : x(0), y(0) {}
Coord( unsigned xIn, unsigned yIn ) : x( xIn ), y( yIn ) {}
};
class DefenderBoard {
private:
std::string filename;
unsigned testcase;
unsigned gridsize_x;
unsigned gridsize_y;
unsigned numTowers;
std::vector<unsigned> penalties;
std::vector<Coord> cells;
public:
explicit DefenderBoard( const std::string& filenameIn );
~DefenderBoard();
void getPenalties( std::vector<unsigned>& penalties ) const;
private:
void getDataFromFile();
void calculatePenalty();
};
#endif
DefenderBoard.cpp
#include "DefenderBoard.h"
DefenderBoard::DefenderBoard( const std::string& filenameIn ) :
filename( filenameIn ),
gridsize_x( 0 ), gridsize_y( 0 ),
testcase( 0 ),
numTowers( 0 ),
penalty( 0 ) {
getDataFromFile();
}
DefenderBoard::~DefenderBoard() {
}
void DefenderBoard::getPenalties( std::vector<unsigned>& penaltiesOut ) const {
penaltiesOut = penalties;
}
void DefenderBoard::getDataFromFile() {
std::ifstream file;
file.open( filename );
if ( !file.is_open() ) {
std::ostringstream strStream;
strStream << __FUNCTION__ << " failed to read in file[" << filename << "]";
throw ExceptionHandler( strStream );
}
file >> testcase;
Coord towerCoord;
for ( unsigned t = 0; t < testcase; ++t ) {
file >> gridsize_x;
file >> gridsize_y;
file >> numTowers;
for ( unsigned c = 0; c < numTowers; ++c ) {
file >> towerCoord.x;
file >> towerCoord.y;
cells.push_back( towerCoord );
}
calculatePenalty();
cells.clear();
}
file.close();
}
bool compareCoordsX( const struct Coord& a, const struct Coord& b ) {
return a.x > b.x;
}
bool compareCoordsY( const struct Coord& a, const struct Coord& b ) {
return a.y > b.y;
}
void DefenderBoard::calculatePenalty() {
std::vector<unsigned> xValDiff;
std::vector<unsigned> yValDiff;
unsigned diff = 0;
std::stable_sort( cells.begin(), cells.end(), compareCoordsX );
unsigned idx = 0;
for ( ; idx < cells.size(); ++idx ) {
if ( idx == 0 ) {
diff = gridsize_x - cells[idx].x;
xValDiff.push_back( diff );
} else {
diff = cells[idx-1].x - cells[idx].x - 1;
xValDiff.push_back( diff );
}
}
xValDiff.push_back( cells.back().x - 1 );
std::stable_sort( cells.begin(), cells.end(), compareCoordsY );
idx = 0;
diff = 0;
for ( ; idx < cells.size(); ++idx ) {
if ( idx == 0 ) {
diff = gridsize_y - cells[idx].y;
yValDiff.push_back( diff );
} else {
diff = cells[idx-1].y - cells[idx].y - 1;
yValDiff.push_back( diff );
}
}
yValDiff.push_back( cells.back().y - 1 );
unsigned largestX = xValDiff[0];
unsigned largestY = yValDiff[0];
idx = 0;
for ( ; idx < cells.size(); ++idx ) {
if ( xValDiff[idx] > largestX ) {
largestX = xValDiff[idx];
}
if ( yValDiff[idx] > largestY ) {
largestY = yValDiff[idx];
}
}
penalties.push_back( largestX * largestY );
}
main.cpp
#include <iostream>
#include "DefenderBoard.h"
int main() {
std::vector<unsigned> penalties;
DefenderBoard board( "pieces.txt" );
board.getPenalties( penalties );
unsigned idx = 0;
for ( ; idx < penalties.size(); ++idx ) {
std::cout << penalties[idx] << " ";
}
std::cout << std::endl;
return 0;
}
12
- :
pieces.txt
2
15 8 3
3 8
11 2
8 6
12 10 4
2 2
9 7
3 9
8 5
12 8
:
, , MxN. , 8x8, , [12,2] [5,9], , . .
, . 1, , , , 1 . . . x, y. , , x y, .
, , , , , , - . . , . x y. , N. . - N, N + 1, - , N - . , - x y, .
:
, , ... , - "" "" OO... , -, , . , , , , , . , 1 2
, , , . , OO-, , . , .
- -
lisyarus OO.
#include <string>
#include <vector>
#include <algorithm>
#include <fstream>
struct TowerCoordinate {
unsigned x;
unsigned y;
TowerCoordinate() : x(0), y(0) {}
TowerCoordinate( unsigned xIn, unsigned yIn ) : x( xIn ), y( yIn ) {}
};
struct GridSize {
unsigned width;
unsigned height;
GridSize() : width( 0 ), height( 0 ) {}
GridSize( unsigned widthIn, unsigned heightIn ) : width( widthIn ), height( heightIn ) {}
};
bool compareCoordsX( const struct TowerCoordinate& a, const struct TowerCoordinate& b ) {
return a.x > b.x;
}
bool compareCoordsY( const struct TowerCoordinate& a, const struct TowerCoordinate& b ) {
return a.y > b.y;
}
unsigned calculatePenalties( std::vector<TowerCoordinate>& towerLocations, GridSize& gridSize ) {
std::vector<unsigned> xValDiff, yValDiff;
unsigned diff = 0;
unsigned idx = 0;
std::stable_sort( towerLocations.begin(), towerLocations.end(), compareCoordsX );
for ( ; idx < towerLocations.size(); ++idx ) {
if ( idx == 0 ) {
diff = gridSize.width - towerLocations[idx].x;
xValDiff.push_back( diff );
} else {
diff = towerLocations[idx-1].x - towerLocations[idx].x - 1;
xValDiff.push_back( diff );
}
}
xValDiff.push_back( towerLocations.back().x - 1 );
idx = 0;
diff = 0;
std::stable_sort( towerLocations.begin(), towerLocations.end(), compareCoordsY );
for ( ; idx < towerLocations.size(); ++idx ) {
if ( idx == 0 ) {
diff = gridSize.height - towerLocations[idx].y;
yValDiff.push_back( diff );
} else {
diff = towerLocations[idx-1].y - towerLocations[idx].y - 1;
yValDiff.push_back( diff );
}
}
yValDiff.push_back( towerLocations.back().y - 1 );
unsigned largestX = xValDiff[0];
unsigned largestY = yValDiff[0];
idx = 0;
for ( ; idx < towerLocations.size(); ++idx ) {
if ( xValDiff[idx] > largestX ) {
largestX = xValDiff[idx];
}
if ( yValDiff[idx] > largestY ) {
largestY = yValDiff[idx];
}
}
return (largestX * largestY);
}
std::vector<unsigned> getDefenderDataFromFile( const std::string& filename, unsigned& numTestCases, GridSize& gridSize, unsigned& numTowers, std::vector<TowerCoordinate>& towerLocations ) {
std::ifstream file;
file.open( filename );
if ( !file.is_open() ) {
std::ostringstream strStream;
strStream << __FUNCTION__ << " failed to read in file[" << filename << "]";
throw ExceptionHandler( strStream );
}
file >> numTestCases;
TowerCoordinate towerCoord;
std::vector<unsigned> penalties;
for ( unsigned t = 0; t < numTestCases; ++t ) {
file >> gridSize.width;
file >> gridSize.height;
file >> numTowers;
for ( unsigned c = 0; c < numTowers; ++c ) {
file >> towerCoord.x;
file >> towerCoord.y;
towerLocations.push_back( towerCoord );
}
unsigned currentPenalty = calculatePenalties( towerLocations, gridSize );
penalties.push_back( currentPenalty );
towerLocations.clear();
}
file.close();
return penalties;
}
int main() {
unsigned numTestCases = 0;
unsigned numTowers = 0;
GridSize gridSize;
std::vector<TowerCoordinate> towerLocations;
std::vector<unsigned> penalties;
penalties = getDefenderDataFromFile( "pieces.txt", numTestCases, gridSize, numTowers, towerLocations );
unsigned idx = 0;
for ( ; idx < penalties.size(); ++idx ) {
std::cout << penalties[idx] << " ";
}
std::cout << std::endl;
return 0;
}
The only thing that should be aware of this current implementation of this algorithm is that the tower location vector is cleared after each test case, so as soon as you get the final results of all penalties for the tower coordinate container for the current frame frame, it will consist only of the most recent set of positions and will not contain any previous iterations. And once again there are no boundaries for checking the coordinates of the tower relative to the size of the grid.