|
|
The brute force algorithm:
cin >> k; // k = # commands of the painter
for ( int q = 0; q < k; q++ )
{
cin >> letter;
cin >> number;
if ( letter == 'R' )
{
// Flip row "number"
for ( int y = 1; y <= n; y++ )
grid[number][y] = ! grid[number][y];
// Note: !true = false, !false = true
}
else
{
// Flip column "number"
for ( int x = 1; x <= m; x++ )
grid[x][number] = ! grid[x][number];
// Note: !true = false, !false = true
}
}
|
DEMO: CCC/2021/Progs/j5-brute-force.cc
|
|
We can start in any state of the canvas We apply R m and then C n The result is Z1 We start again in any state of the canvas We apply C n and then R m The result is Z2 We get the same result ! So order does not matter |
We can start in any state of the canvas We apply R m and then R n The result is Z1 We start again in any state of the canvas We apply R n and then R m The result is Z2 We get the same result ! So order does not matter |
Note: Same for C m and C n
|
There is one more property that you need to discover to get a speedy algorithm.
R m and R m not only commute
The cancel each other out !!
The trick to speed up the solution is:
Cancel as many operations out as you can.
|
Note: Same for C n and C n - they also cancel
cin >> k; // k = # commands of the painter
/* -------------------------------------
Store all the painting commands
------------------------------------- */
for ( int q = 0; q < k; q++ )
{
Read in a command;
Store it;
}
/* ---------------------------------------------
Perform ONLY commands issued ODD # times !
--------------------------------------------- */
for ( each command X )
{
if ( command X is issued an odd number of times )
do the command
}
|
Task: finds a data structure that allows you to count the different commands fast !
// Used to eliminate duplicate commands
int Rcommands[m+1], Ccommands[n+1];
for (int x = 1; x <= m; x++)
Rcommands[x] = 0;
for (int x = 1; x <= n; x++)
Ccommands[x] = 0;
// Read in commands
int k;
cin >> k;
char letter;
int number;
// Read in commands and COLLADE duplicate commands
for ( int q = 0; q < k; q++ )
{
cin >> letter;
cin >> number;
if ( letter == 'R' )
Rcommands[number]++; // One more R n
else
Ccommands[number]++; // One more C n
}
|
bool grid[m+1][n+1];
for ( int x = 1; x <= m; x++ )
for ( int y = 1; y <= n; y++ )
grid[x][y] = false; // false = B
// Process Row commands
for ( int x = 1; x <= m; x++ )
if ( Rcommands[x]%2 == 1 )
// Flip row x if this R command has an ODD count
for ( int y = 1; y <= n; y++ )
grid[x][y] = ! grid[x][y]; // !true = false, !false = true
// Process Column commands
for ( int y = 1; y <= n; y++ )
if ( Ccommands[y]%2 == 1 )
// Flip column y if this C command has an ODD count
for ( int x = 1; x <= m; x++ )
grid[x][y] = ! grid[x][y]; // !true = false, !false = true
|
You can count the number of true values in the cells...