1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
int thick; // thickness of mortar joint (0 or 1)
int n; // number of bricks
int rows; // number of rows
int width; // number of positions filled by either brick or mortar
int last; // last index in availability array
//========
int next( int r, int level, const vector< vector<int> > &mortar, const vector<bool> &avail, const vector< vector<bool> > &brick, int &length )
{
int prev = -1; // Effective position of left end stop for level 0
if ( level > 0 ) prev = mortar[r][level-1]; // Otherwise, mortar position to the left
int pos = max( prev + thick, mortar[r][level] ) + 1; // First trial; must leave minimum brick space and increase any current
int posmax = min( last, prev + n + thick ); // Maximum trial position
while ( pos <= posmax ) // Search all possible next positions
{
if ( avail[pos] ) // ... that haven't been used yet
{
length = pos - prev - thick; // The length of a brick, given these mortar positions
if ( brick[r][length] ) return pos; // If this brick still available, use it
}
pos++;
}
return -1; // Failed to place one
}
//========
void draw1( const vector< vector<int> > &mortar )
{
string layer = '|' + string( width, '-' ) + '|';
for ( int r = 0; r < rows; r++ )
{
string line = layer;
for ( int i = 0; i < n - 1; i++ ) line[ 1 + mortar[r][i] ] = '|';
cout << line << '\n';
}
}
//========
void draw0( const vector< vector<int> > &mortar )
{
string layer = "|-";
for ( int i = 1; i <= width - 1; i++ ) layer += " -";
layer += '|';
string line0 = "| " + string( 2 * ( width - 1 ), ' ' ) + '|';
cout << layer << '\n';
for ( int r = 0; r < rows; r++ )
{
string line = line0;
for ( int i = 0; i < n - 1; i++ ) line[ 2 + 2 * mortar[r][i] ] = '|';
cout << line << '\n' << layer << '\n';
}
}
//========
int main()
{
cout << "Enter the joint thickness ( 0 or 1 ): "; cin >> thick;
cout << "Enter the number of bricks ( > 1 ): " ; cin >> n;
width = n * ( n + 1 ) / 2 + ( n - 1 ) * thick;
int maxrows = ( width - 1 - thick ) / ( n - 1 ); // Upper bound (not necessarily achievable)
cout << "Enter the number of rows: ( <= " << maxrows << " ): "; cin >> rows;
last = width - 2; // Last index available for mortar
vector<bool> avail( last + 1 , true ); // Slots available for mortar
if ( thick == 1 ) avail[0] = false;
vector< vector<int> > mortar( rows, vector<int>( n - 1, -1 ) ); // Mortar positions by row and level; -1 means not set
vector< vector<bool> > brick( rows, vector<bool>( n + 1, true ) ); // Brick lengths still available ([0] component isn't used)
// ALGORITHM: find lowest legitimate slot; if dead end then back up one by one and retry
int length = 0; // Length of a brick (if placeable)
int r = 0; // r is row
int level = 0; // Level is mortar number in that row (counting from 0)
while ( true )
{
int m = next( r, level, mortar, avail, brick, length ); // Lowest legitimate slot (ignoring current, if any)
// cout << level << " " << r << " " << m << endl;
if ( r == 0 && level == 0 && m < 0 ) // This can take a ... VERY ... LONG ... time!
{
cout << "Impossible" << endl;
return 1;
}
if ( m >= 0 ) // If there is a slot available
{
mortar[r][level] = m; // ... fill it with mortar
avail[m] = brick[r][length] = false; // ... make it unavailable
r++; if ( r == rows ) { r = 0; level++; } // ... move to next row
}
else // If there isn't one ...
{
mortar[r][level] = -1; // ... cancel this spot
r--; if ( r < 0 ) { r = rows - 1; level--; } // ... and move back a row
length = mortar[r][level] - thick - ( level == 0 ? -1 : mortar[r][level-1] );
avail[mortar[r][level]] = brick[r][length] = true; // Clear this position, as we must update it next loop
}
if ( level == n - 1 ) break; // All mortar in place
}
if ( thick == 0 ) draw0( mortar );
else draw1( mortar );
}
|