C++大学教程(第七版)课后习题答案第七章

427 阅读6分钟

第七章

7.10(销售人员薪金范围)

#include <iostream> 
#include <iomanip> 
using namespace std;

void wages( int [] );
void display( const int [] );

int main()
{
   int salaries[ 11 ] = {};
   cout << fixed << showpoint;
   wages( salaries ); 
   display( salaries ); 
} 

void wages( int money[] )
{
   double sales;
   double i = 0.09;
   cout << "Enter employee gross sales (-1 to end): ";
   cin >> sales;
   while ( sales != -1 ) 
   {
      double salary = 200.0 + sales * i;
      cout << setprecision( 2 ) << "Employee Commission is $" 
         << salary << '\n';
      int x = static_cast< int > ( salary ) / 100;
      money[ ( x < 10 ? x : 10 ) ]++;
      cout << "\nEnter employee gross sales (-1 to end): ";
      cin >> sales;
   } 
}

void display( const int dollars[] )
{
   cout << "Employees in the range:";
   for ( int i = 2; i < 10; i++ )
      cout << "\n$" << i << "00-$" << i << "99 : " << dollars[ i ];
   cout << "\nOver $1000: " << dollars[ 10 ] << endl;
} 

7.13(利用array对象去重)

#include <iostream> 
using namespace std;

int main()
{
   const int SIZE = 20; 
   int a[ SIZE ] = {};
   int subscript = 0;
   int duplicate;
   int value; 
   cout << "Enter 20 integers between 10 and 100:\n";
   for ( int i = 0; i < SIZE; ) 
   {
      duplicate = 0;
      cin >> value;
      if ( value >= 10 && value <= 100 )
      {
         for ( int j = 0; j < subscript; j++ )
         {
            if ( value == a[ j ] ) 
            {
               duplicate = 1;
               break;
            }
         }
         if ( !duplicate )
         {
            a[ subscript++ ] = value;
            ++i;
         } 
         else
            cout << "Duplicate number.\n";
      }
      else
         cout << "Invalid number.\n";
   } 
   cout << "\nThe nonduplicate values are:\n";

   for ( int i = 0; i < SIZE; i++ )
      cout << a[ i ] << ' ';
   cout << endl;
}

7.14(利用vector对象去重)

#include <iostream> 
#include <vector>
using namespace std;

int main()
{
    const int SIZE = 20;
    vector<int> a(SIZE,0);
    int subscript = 0;
    int duplicate;
    int value;
    cout << "Enter 20 integers between 10 and 100:\n";
    for (int i = 0; i < SIZE; )
    {
        duplicate = 0;
        cin >> value;
        if (value >= 10 && value <= 100)
        {
            for (int j = 0; j < subscript; j++)
            {
                if (value == a[j])
                {
                    duplicate = 1;
                    break;
                }
            } 
            if (!duplicate)
            {
                a[i]=value;
                subscript++;
                ++i;
            }
            else
                cout << "Duplicate number.\n";
        }
        else
            cout << "Invalid number.\n";
    }
    cout << "\nThe nonduplicate values are:\n";
    for (int i = 0; i < SIZE; i++)
        cout << a[i] << ' ';
    cout << endl;
}

7.15(二维array对象初始化)

#include <iostream> 
#include <vector>
#include <array>
using namespace std;

int main()
{
    array < array<int, 5>, 3 > sales= {};
    for (size_t row = 0; row < sales.size(); ++row)
        for (size_t column = 0; column < sales[row].size(); ++column) {
            sales[row][column] = 0;
            cout << "sales["<<row<<"]["<<column<<"] "<< "has been initialized." << endl;
        }
}

7.16(掷双骰)

#include <iostream> 
#include <iomanip> 
#include <cstdlib>
#include <ctime>
using namespace std;

int main()
{
    const long ROLLS = 36000;
    const int SIZE = 13;
    int expected[SIZE] = { 0, 0, 1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1 };
    int x; 
    int y;
    int sum[SIZE] = {};
    srand(time(0));
    for (long i = 1; i <= ROLLS; i++)
    {
        x = 1 + rand() % 6;
        y = 1 + rand() % 6;
        sum[x + y]++;
    }
    cout << setw(10) << "Sum" << setw(10) << "Total" << setw(10)
        << "Expected" << setw(10) << "Actual\n" << fixed << showpoint;
    for (int j = 2; j < SIZE; j++)
        cout << setw(10) << j << setw(10) << sum[j]
        << setprecision(3) << setw(9)
        << 100.0 * expected[j] / 36 << "%" << setprecision(3)
        << setw(9) << 100.0 * sum[j] / ROLLS << "%\n";
}

7.18(掷骰子游戏的改进)

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;

int rollDice(); 

int main()
{
   enum Outcome { CONTINUE, WIN, LOSE };
   const int SIZE = 22;
   const int ROLLS = 1000;
   int gameStatus;
   int sum;
   int myPoint;
   int roll;
   int length = 0;
   int wins[ SIZE ] = {};
   int losses[ SIZE ] = {};
   int winSum = 0; 
   int loseSum = 0;

   srand( time( 0 ) );
   
   for ( int i = 1; i <= ROLLS; i++ ) 
   {
      sum = rollDice();
      roll = 1;
      switch ( sum )
      {
         case 7: case 11:
            gameStatus = WIN;
            break;
         case 2: case 3: case 12:
            gameStatus = LOSE;
            break;
         default:
            gameStatus = CONTINUE;
            myPoint = sum;
            break;
      } 
      while ( gameStatus == CONTINUE ) 
      {
         sum = rollDice();
         roll++;

         if ( sum == myPoint )
            gameStatus = WIN;
         else if ( sum == 7 )
            gameStatus = LOSE;
      } 
      if ( roll > 21 )
         roll = 21;
      if ( gameStatus == WIN ) 
      {
         wins[ roll ]++;
         winSum++;
      }
      else 
      {
         losses[ roll ]++;
         loseSum++;
      } 
   } 
   cout << "Games won or lost after the 20th roll" 
      << "\nare displayed as the 21st roll.\n\n";
   for ( int z = 1; z <= 21; ++z ) 
      cout << setw( 3 ) << wins[ z ] << " games won and " << setw( 3 )
         << losses[ z ] << " games lost on roll " << z << '\n';
   cout << fixed << showpoint << "\nThe chances of winning are " << winSum 
      << " / " << winSum + loseSum << " = " << setprecision( 2 )
      << 100.0 * winSum / ( winSum + loseSum ) << "%\n";
   for ( int k = 1; k <= 21; k++ )
      length += wins[ k ] * k + losses[ k ] * k;
   cout << "The average game length is " << setprecision( 2 )
      << length / 1000.0 << " rolls." << endl;
}

int rollDice()
{
   int die1 = 1 + rand() % 6;
   int die2 = 1 + rand() % 6;
   return die1 + die2; // return total of two dice
} 

7.19(将vector对象的例子转换成array对象)

#include <iostream> 
#include <iomanip> 
#include <array>
using namespace std;

void wages(array<int,11>);
void display(const array<int,11>);

int main()
{
    array<int,11> salaries= {};
    cout << fixed << showpoint;
    wages(salaries);
    display(salaries);
}

void wages(array<int,11> money)
{
    double sales;
    double i = 0.09;
    cout << "Enter employee gross sales (-1 to end): ";
    cin >> sales;
    while (sales != -1)
    {
        double salary = 200.0 + sales * i;
        cout << setprecision(2) << "Employee Commission is $"
            << salary << '\n';
        int x = static_cast<int> (salary) / 100;
        money[(x < 10 ? x : 10)]++;
        cout << "\nEnter employee gross sales (-1 to end): ";
        cin >> sales;
    }
}

void display(const array<int,11> dollars)
{
    cout << "Employees in the range:";
    for (int i = 2; i < 10; i++)
        cout << "\n$" << i << "00-$" << i << "99 : " << dollars[i];
    cout << "\nOver $1000: " << dollars[10] << endl;
}

7.21(销售汇总)

#include <iostream> 
#include <iomanip>
using namespace std;

int main()
{
   const int PEOPLE = 5;
   const int PRODUCTS = 6;
   double sales[ PEOPLE ][ PRODUCTS ] = { 0.0 };
   double value;
   double totalSales;
   double productSales[ PRODUCTS ] = { 0.0 };
   int salesPerson;
   int product;
   cout << "Enter the salesperson (1 - 4), product number (1 - 5), and "
      << "total sales.\nEnter -1 for the salesperson to end input.\n";
   cin >> salesPerson; 
   while ( salesPerson != -1 ) 
   {
      cin >> product >> value;
      sales[ salesPerson ][ product ] += value;
      cin >> salesPerson;
   }    
   cout << "\nThe total sales for each salesperson are displayed at the "
      << "end of each row,\n" << "and the total sales for each product "
      << "are displayed at the bottom of each column.\n " << setw( 12 ) 
      << 1 << setw( 12 ) << 2 << setw( 12 ) << 3 << setw( 12 ) << 4 
      << setw( 12 ) << 5 << setw( 13 ) << "Total\n" << fixed << showpoint;
   for ( int i = 1; i < PEOPLE; i++ ) 
   {
      totalSales = 0.0;
      cout << i;
      for ( int j = 1; j < PRODUCTS; j++ ) 
      {
         totalSales += sales[ i ][ j ];
         cout << setw( 12 ) << setprecision( 2 ) << sales[ i ][ j ];
         productSales[ j ] += sales[ i ][ j ];
      } 
      cout << setw( 12 ) << setprecision( 2 ) << totalSales << '\n';
   } 
   cout << "\nTotal" << setw( 8 ) << setprecision( 2 ) 
      << productSales[ 1 ];
   for ( int j = 2; j < PRODUCTS; j++ )
      cout << setw( 12 ) << setprecision( 2 ) << productSales[ j ];
   cout << endl;
}

7.22(骑士巡游)

Part b

#include <iostream> 
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;

const int SIZE = 8;

void clearBoard(int[][SIZE]);
void printBoard(const int[][SIZE]);
bool validMove(int, int, const int[][SIZE]);

int main()
{
    int board[SIZE][SIZE];
    int currentRow;
    int currentColumn;
    int moveNumber = 1;
    int testRow;
    int testColumn;
    int horizontal[SIZE] = { 2, 1, -1, -2, -2, -1, 1, 2 };
    int vertical[SIZE] = { -1, -2, -2, -1, 1, 2, 2, 1 };
    int moveType;
    bool done;
    bool goodMove;

    srand(time(0));

    clearBoard(board);
    currentRow = rand() % 8;
    currentColumn = rand() % 8;
    board[currentRow][currentColumn] = moveNumber++;
    done = false;
    while (!done)
    {
        moveType = 0;
        testRow = currentRow + vertical[moveType];
        testColumn = currentColumn + horizontal[moveType];
        goodMove = validMove(testRow, testColumn, board);
        if (goodMove)
        {
            currentRow = testRow;
            currentColumn = testColumn;
            board[currentRow][currentColumn] = moveNumber++;
        }
        else
        {
            for (int count = 0; count < SIZE - 1 && !goodMove; count++)
            {
                moveType = ++moveType % SIZE;
                testRow = currentRow + vertical[moveType];
                testColumn = currentColumn + horizontal[moveType];
                goodMove = validMove(testRow, testColumn, board);
                if (goodMove)
                {
                    currentRow = testRow;
                    currentColumn = testColumn;
                    board[currentRow][currentColumn] = moveNumber++;
                }
            }
            if (!goodMove)
                done = true;
        }
        if (moveNumber - 1 == 64)
            done = true;
    }
    cout << "The tour ended with " << moveNumber - 1 << " moves.\n";
    if (moveNumber - 1 == 64)
        cout << "This was a full tour!\n\n";
    else
        cout << "This was not a full tour.\n\n";
    cout << "The board for this test is:\n\n";
    printBoard(board);
}

void clearBoard(int workBoard[][SIZE])
{
    for (int row = 0; row < SIZE; row++)
    {
        for (int col = 0; col < SIZE; col++)
            workBoard[row][col] = 0;
    }
}

void printBoard(const int workBoard[][SIZE])
{
    cout << "   0  1  2  3  4  5  6  7\n";
    for (int row = 0; row < SIZE; row++)
    {
        cout << row;
        for (int col = 0; col < SIZE; col++)
            cout << setw(3) << workBoard[row][col];
        cout << '\n';
    }
    cout << endl;
}

bool validMove(int row, int column, const int workBoard[][SIZE])
{
    return (row >= 0 && row < SIZE&& column >= 0 && column < SIZE
        && workBoard[row][column] == 0);
}

Part c

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;
const int SIZE = 8;

void clearBoard( int [][ SIZE ] );
void printBoard( const int [][ SIZE ] );
bool validMove( int, int, const int [][ SIZE ] );

int main()
{
   int board[ SIZE ][ SIZE ];
   int currentRow;
   int currentColumn;
   int moveNumber = 1;
   int access[ SIZE ][ SIZE ] = { 2, 3, 4, 4, 4, 4, 3, 2,
                                  3, 4, 6, 6, 6, 6, 4, 3,
                                  4, 6, 8, 8, 8, 8, 6, 4,
                                  4, 6, 8, 8, 8, 8, 6, 4,
                                  4, 6, 8, 8, 8, 8, 6, 4,
                                  4, 6, 8, 8, 8, 8, 6, 4,
                                  3, 4, 6, 6, 6, 6, 4, 3,
                                  2, 3, 4, 4, 4, 4, 3, 2 };

   int testRow;
   int testColumn;
   int minRow;
   int minColumn; 
   int minAccess = 9;
   int accessNumber;
   int horizontal[ SIZE ] = { 2, 1, -1, -2, -2, -1, 1, 2 };
   int vertical[ SIZE ] = { -1, -2, -2, -1, 1, 2, 2, 1 };
   bool done;

   srand( time( 0 ) );
   
   clearBoard( board );
   currentRow = rand() % 8;
   currentColumn = rand() % 8;
   board[ currentRow ][ currentColumn ] = moveNumber++;
   done = false;
   while ( !done )
   {
      accessNumber = minAccess;
      for ( int moveType = 0; moveType < SIZE; ++moveType ) 
      {
         testRow = currentRow + vertical[ moveType ];
         testColumn = currentColumn + horizontal[ moveType ];
         if ( validMove( testRow, testColumn, board ) ) 
         {
            if ( access[ testRow ][ testColumn ] < accessNumber ) 
            {
               accessNumber = access[ testRow ][ testColumn ];
               minRow = testRow;
               minColumn = testColumn;
            }
            access[ testRow ][ testColumn ]--;
         }
      }
      if ( accessNumber == minAccess )
         done = true;
      else 
      {
         currentRow = minRow;
         currentColumn = minColumn;
         board[ currentRow ][ currentColumn ] = moveNumber++;
      }
   } 
   cout << "The tour ended with " << moveNumber - 1 << " moves.\n";
   if ( moveNumber - 1 == 64 )
      cout << "This was a full tour!\n\n";
   else
      cout << "This was not a full tour.\n\n";

   cout << "The board for this test is:\n\n";
   printBoard( board );
}

void clearBoard( int workBoard[][ SIZE ] )
{
   for ( int row = 0; row < SIZE; row++ )
   {
      for ( int col = 0; col < SIZE; col++ )
         workBoard[ row ][ col ] = 0;
   } 
} 

void printBoard( const int workBoard[][ SIZE ] )
{
   cout << "   0  1  2  3  4  5  6  7\n";
   for ( int row = 0; row < SIZE; row++ ) 
   {
      cout << row;
      for ( int col = 0; col < SIZE; col++ )
         cout << setw( 3 ) << workBoard[ row ][ col ];
      cout << '\n';
   }
   cout << endl;
}

bool validMove( int row, int column, const int workBoard[][ SIZE ] )
{
   return ( row >= 0 && row < SIZE && column >= 0 && column < SIZE
      && workBoard[ row ][ column ] == 0 );
}

7.23(骑士巡游:蛮力方法)

Part b

#include <iostream> 
#include <iomanip> 
#include <cstdlib>
#include <ctime>
using namespace std;

const int SIZE = 8;
const int TOURS = 1000;
const int MAXMOVES = 65;

bool validMove( int, int, int, const int [][ SIZE ] );

int main()
{
   int currentRow;
   int currentColumn;
   int moveType;
   int moveNumber;
   int testRow;
   int testColumn;
   int moveTotal[ MAXMOVES ] = {};
   int goodMove;
   int board[ SIZE ][ SIZE ];
   int horizontal[ SIZE ] = { 2, 1, -1, -2, -2, -1, 1, 2 };
   int vertical[ SIZE ] = { -1, -2, -2, -1, 1, 2, 2, 1 };
   bool done;
   srand( time( 0 ) );
   for ( int i = 0; i < TOURS; ++i )
   {
      for ( int row = 0; row < SIZE; row++ )
      {
         for ( int col = 0; col < SIZE; col++ )
            board[ row ][ col ] = 0;
      }
      moveNumber = 1;
      currentRow = rand() % SIZE;
      currentColumn = rand() % SIZE;
      board[ currentRow ][ currentColumn ] = moveNumber++;
      done = false;
      while ( !done ) 
      {
         moveType = rand() % SIZE;
         testRow = currentRow + vertical[ moveType ];
         testColumn = currentColumn + horizontal[ moveType ];
         goodMove = validMove( testRow, testColumn, moveType, board );
         if ( goodMove ) 
         {
            currentRow = testRow;
            currentColumn = testColumn;
            board[ currentRow ][ currentColumn ] = moveNumber++;
         }
         else
         {
            for ( int count = 0; count < SIZE - 1 && !goodMove; count++ )
            {
               moveType = ++moveType % SIZE;
               testRow = currentRow + vertical[ moveType ];
               testColumn = currentColumn + horizontal[ moveType ];
               goodMove = validMove( testRow, testColumn, moveType, board );
               if ( goodMove ) 
               {
                  currentRow = testRow;
                  currentColumn = testColumn;
                  board[ currentRow ][ currentColumn ] = moveNumber++;
               }
            }
            if ( !goodMove )
               done = true;
         }
         if ( moveNumber - 1 == 64 ) 
            done = true;
      }
      moveTotal[ moveNumber ]++;
   }
   for ( int j = 1; j < MAXMOVES; j++ )
   {
      if ( moveTotal[ j ] )
         cout << "There were " << moveTotal[ j ] << " tours of " << j
            << " moves." << endl;
   }
}

bool validMove(  
   int testRow, int testColumn, int moveType, const int board[][ SIZE ] )
{
   if ( testRow >= 0 && testRow < SIZE && testColumn >= 0 && 
      testColumn < SIZE )
      return board[ testRow ][ testColumn ] != 0 ? false : true;
   else
      return false;
}

Part c

#include <iostream> 
#include <iomanip> 
#include <cstdlib>
#include <ctime>
using namespace std;

const int SIZE = 8;
const int TOURS = 1000;
const int MAXMOVES = 65;

bool validMove(int, int, int, const int[][SIZE]);

int main()
{
    int currentRow;
    int currentColumn;
    int moveType;
    int moveNumber;
    int testRow;
    int testColumn;
    int moveTotal[MAXMOVES] = {};
    int goodMove;
    int board[SIZE][SIZE];
    int horizontal[SIZE] = { 2, 1, -1, -2, -2, -1, 1, 2 };
    int vertical[SIZE] = { -1, -2, -2, -1, 1, 2, 2, 1 };
    bool done;
    srand(time(0));
    do
    {
        for (int row = 0; row < SIZE; row++)
        {
            for (int col = 0; col < SIZE; col++)
                board[row][col] = 0;
        }
        moveNumber = 1;
        currentRow = rand() % SIZE;
        currentColumn = rand() % SIZE;
        board[currentRow][currentColumn] = moveNumber++;
        done = false;
        while (!done)
        {
            moveType = rand() % SIZE;
            testRow = currentRow + vertical[moveType];
            testColumn = currentColumn + horizontal[moveType];
            goodMove = validMove(testRow, testColumn, moveType, board);
            if (goodMove)
            {
                currentRow = testRow;
                currentColumn = testColumn;
                board[currentRow][currentColumn] = moveNumber++;
            }
            else
            {
                for (int count = 0; count < SIZE - 1 && !goodMove; count++)
                {
                    moveType = ++moveType % SIZE;
                    testRow = currentRow + vertical[moveType];
                    testColumn = currentColumn + horizontal[moveType];
                    goodMove = validMove(testRow, testColumn, moveType, board);
                    if (goodMove)
                    {
                        currentRow = testRow;
                        currentColumn = testColumn;
                        board[currentRow][currentColumn] = moveNumber++;
                    }
                }
                if (!goodMove)
                    done = true;
            }
            if (moveNumber - 1 == 64)
                done = true;
        }
        moveTotal[moveNumber]++;
    } while (moveNumber - 1 < 64);
    for (int j = 1; j < MAXMOVES; j++)
    {
        if (moveTotal[j])
            cout << "There were " << moveTotal[j] << " tours of " << j
            << " moves." << endl;
    }
}

bool validMove(
    int testRow, int testColumn, int moveType, const int board[][SIZE])
{
    if (testRow >= 0 && testRow < SIZE && testColumn >= 0 &&
        testColumn < SIZE)
        return board[testRow][testColumn] != 0 ? false : true;
    else
        return false;
}

7.24(八皇后问题)

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;

bool queenCheck(const char[][8], int, int);
void placeQueens(char[][8]);
void printBoard(const char[][8]);
void xConflictSquares(char[][8], int, int);
void xDiagonals(char[][8], int, int);
bool availableSquare(const char[][8]);

inline int validMove( const char board[][ 8 ], int row, int col )
{
    return (row >= 0 && row < 8 && col >= 0 && col < 8);
}

int main()
{
    char board[8][8] = { '\0' };
    srand(time(0));
    placeQueens(board); // try to place queens on board
    printBoard(board); // print board
}

bool availableSquare( const char board[][ 8 ] )
{
   for ( int row = 0; row < 8; ++row )
   {
      for ( int col = 0; col < 8; ++col )
      {
          if (board[row][col] == '\0')
              return false;
      }
   }
   return true;
}

void placeQueens( char board[][ 8 ] )
{
    const char QUEEN = 'Q';
    int rowMove;
    int colMove;
    int queens = 0;
    bool done = false;
   while ( queens < 8 && !done )
   {
       rowMove = rand() % 8;
       colMove = rand() % 8;
       // test if queen can be placed on board
       if ( queenCheck( board, rowMove, colMove ) ) 
       {
           board[rowMove][colMove] = QUEEN;
           xConflictSquares(board, rowMove, colMove);
           queens++;
       }
       // determine if there are available squares
       done = availableSquare(board);
   }
}

// function to mark occupied rows, columns and diagonals
void xConflictSquares( char board[][ 8 ], int row, int col )
{ 
   for ( int loop = 0; loop < 8; ++loop ) 
   {
      // place an '*' in the row occupied by the queen
       if (board[row][loop] == '\0')
           board[row][loop] = '*';

      // place an '*' in the col occupied by the queen
       if (board[loop][col] == '\0')
           board[loop][col] = '*';
   }
   // place an '*' in the diagonals occupied by the queen
   xDiagonals(board, row, col);
} // end function xConflictSquares 

// function to determine if row, column, diagonal is occupied
bool queenCheck( const char board[][ 8 ], int row, int col )
{
    int r = row;
    int c = col;
   for ( int d = 0; d < 8; d++ )
   {
       if (board[row][d] == 'Q' || board[d][col] == 'Q')
           return false;
   }
   for ( int e = 0; e < 8 && validMove( board, --r, --c ); e++ )
   {
       if (board[r][c] == 'Q')
           return false;
   }
   r = row;
   c = col;
   for ( int f = 0; f < 8 && validMove( board, --r, ++c ); f++ )
   {
       if (board[r][c] == 'Q')
           return false;
   }
   r = row;
   c = col;
   for ( int g = 0; g < 8 && validMove( board, ++r, --c ); g++ )
   {
       if (board[r][c] == 'Q')
           return false;
   }
   r = row;
   c = col;
   for ( int h = 0; h < 8 && validMove( board, ++r, ++c ); h++ )
   {
       if (board[r][c] == 'Q')
           return false;
   } 
   return true;
}

void xDiagonals( char board[][ 8 ], int row, int col )
{
    int r = row, c = col;
    for (int a = 0; a < 8 && validMove(board, --r, --c); a++)
        board[r][c] = '*';
   r = row;
   c = col;
   for ( int b = 0; b < 8 && validMove( board, --r, ++c ); b++ )
      board[ r ][ c ] = '*';
   r = row;
   c = col;
   for ( int d = 0; d < 8 && validMove( board, ++r, --c ); d++ )
      board[ r ][ c ] = '*';
   r = row;
   c = col;
   for ( int e = 0; e < 8 && validMove( board, ++r, ++c ); e++ )
      board[ r ][ c ] = '*';
}

// function to print chess board
void printBoard( const char board[][ 8 ] )
{
    int queens = 0;
    cout << "   0 1 2 3 4 5 6 7\n"; 
    for ( int r = 0; r < 8; r++ ) 
    {
        cout << setw(2) << r << ' ';
        for ( int c = 0; c < 8; c++ ) 
        {
            cout << board[r][c] << ' ';
            if (board[r][c] == 'Q')
                queens++;
        }
        cout << '\n';
    }
    if (queens == 8)
        cout << "\nEight Queens were placed on the board!" << endl;
    else
        cout << '\n' << queens << " Queens were placed on the board.\n";
}

7.26(骑士巡游问题:封闭巡游测试)

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;

const int SIZE = 8;

void clearBoard( int [][ SIZE ] );
void printBoard( const int [][ SIZE ] ); 
bool validMove( int, int, const int [][ SIZE ] ); 

int main()
{
   int board[ SIZE ][ SIZE ];
   int firstMoveRow;
   int firstMoveCol;
   int access[ SIZE ][ SIZE ] = { 2, 3, 4, 4, 4, 4, 3, 2,
                                  3, 4, 6, 6, 6, 6, 4, 3,
                                  4, 6, 8, 8, 8, 8, 6, 4,
                                  4, 6, 8, 8, 8, 8, 6, 4,
                                  4, 6, 8, 8, 8, 8, 6, 4,
                                  4, 6, 8, 8, 8, 8, 6, 4,
                                  3, 4, 6, 6, 6, 6, 4, 3,
                                  2, 3, 4, 4, 4, 4, 3, 2 };
   int currentRow;
   int currentColumn; 
   int moveNumber = 1;
   int testRow; 
   int testColumn;
   int minRow;
   int minColumn;
   int minAccess = 9;
   int accessNumber;
   int horizontal[ SIZE ] = { 2, 1, -1, -2, -2, -1, 1, 2 };
   int vertical[ SIZE ] = { -1, -2, -2, -1, 1, 2, 2, 1 };
   bool done;
   bool closedTour = false;

   srand( time( 0 ) );

   clearBoard( board );
   currentRow = rand() % SIZE;
   currentColumn = rand() % SIZE;
   firstMoveRow = currentRow;
   firstMoveCol = currentColumn;
   board[ currentRow ][ currentColumn ] = moveNumber++;
   done = false;
   while ( !done )
   {
      accessNumber = minAccess;
      for ( int moveType = 0; moveType < SIZE; moveType++ ) 
      {
         testRow = currentRow + vertical[ moveType ];
         testColumn = currentColumn + horizontal[ moveType ];
         if ( validMove( testRow, testColumn, board ) ) 
         {
            if ( access[ testRow ][ testColumn ] < accessNumber ) 
            {
               accessNumber = access[ testRow ][ testColumn ];
               minRow = testRow;
               minColumn = testColumn;
            }
            access[ testRow ][ testColumn ]--;
         }
      }
      if ( accessNumber == minAccess )
         done = true;
      else 
      {
         currentRow = minRow;
         currentColumn = minColumn;
         board[ currentRow ][ currentColumn ] = moveNumber++;
         if ( moveNumber == 64 )
         {
            for ( int m = 0; m < SIZE; ++m ) 
            {
               testRow = currentRow + vertical[ m ];
               testColumn = currentColumn + horizontal[ m ];
               if (testRow == firstMoveRow && testColumn == firstMoveCol)
                  closedTour = true;
            } 
         }
      }
   } 
   cout << "The tour ended with " << moveNumber - 1 << " moves.\n";

   if ( moveNumber - 1 == 64 && closedTour == true )
      cout << "This was a CLOSED tour!\n\n";
   else if ( moveNumber - 1 == 64 )
      cout << "This was a full tour!\n\n";
   else
      cout << "This was not a full tour.\n\n";

   cout << "The board for this test is:\n\n";
   printBoard( board );
}
void clearBoard( int workBoard[][ SIZE ] )
{
   for ( int row = 0; row < SIZE; row++ )
   {
      for ( int col = 0; col < SIZE; col++ )
         workBoard[ row ][ col ] = 0;
   }
}

void printBoard( const int workBoard[][ SIZE ] )
{
   cout << "   0  1  2  3  4  5  6  7\n";
   for ( int row = 0; row < SIZE; row++ ) 
   {
      cout << row;
      for ( int col = 0; col < SIZE; col++ )
         cout << setw( 3 ) << workBoard[ row ][ col ];
      cout << '\n';
   } 
   cout << endl;
}

bool validMove( int row, int column, const int workBoard[][ SIZE ] )
{
   return ( row >= 0 && row < SIZE && column >= 0 && column < SIZE
      && workBoard[ row ][ column ] == 0 );
}

7.27(爱拉托逊斯筛法)

#include <iostream> 
#include <iomanip> 
using namespace std;

int main()
{
   const int SIZE = 1000;
   int array[ SIZE ];
   int count = 0;
   for ( int k = 0; k < SIZE; k++ )
      array[ k ] = 1;
   for ( int i = 1; i < SIZE; i++ )
   {
      if ( array[ i ] == 1 && i != 1 )
      {
         for ( int j = i; j < SIZE; j++ )
         {
            if ( j % i == 0 && j != i )
               array[ j ] = 0;
         }
      }
   }
   for ( int q = 2; q < SIZE; q++ )
   {
      if ( array[ q ] == 1 ) 
      {
         cout << setw( 3 ) << q << " is a prime number.\n";
         count++;
      }
   } 
   cout << "A total of " << count << " prime numbers were found." << endl;
}

7.28(回文)

#include <iostream> 
#include <string>
using namespace std;

bool testPalindrome(string, int, int);

int main()
{
    string input;
    cout << "Enter a sentence:\n";
    getline(cin, input);
    if (testPalindrome(input, 0, input.length() - 1))
        cout << '\"' << input << "\" is a palindrome" << endl;
    else
        cout << '\"' << input << "\" is not a palindrome" << endl;
}

bool testPalindrome(string palindrome, int left, int right)
{
    if (left == right || left > right)
        return true;
    else if (palindrome[left] != palindrome[right])
        return false;
    else
        return testPalindrome(palindrome, left + 1, right - 1);
}

7.29(八皇后问题)

//回溯实现
#include <iostream>
using namespace std;

const int ArSize = 8;
int num = 0;
void solve(bool arr[ArSize][ArSize], int row);
bool check(bool arr[ArSize][ArSize], int row, int column);
void outPut(bool arr[ArSize][ArSize]);

int main()
{
    bool chessboard[ArSize][ArSize];
    // 数组初始化
    for (auto &i : chessboard)
    {
        for (auto &j : i)
        {
            j = false;
        }
    }
    solve(chessboard, 0);
    cout << "八皇后问题共有" << num << "种解!" << endl;
    return 0;
}

// 回溯法
void solve(bool arr[ArSize][ArSize], int row)
{
    for (int column = 0; column < ArSize; ++column)
    {
        arr[row][column] = true;
        if (check(arr, row, column))
        {
            if (row + 1 == ArSize)
            {
                outPut(arr);
            }
            else
            {
                solve(arr, row + 1);
            }
        }
        arr[row][column] = false;
    }
}

// 判断皇后的落点是否合规
bool check(bool arr[ArSize][ArSize], int row, int column)
{
    if (row == 0)
    {
        return true;
    }
    int i, j;
    // 判断纵向是否有冲突
    for (i = 0; i < row; ++i)
    {
        if (arr[i][column])
        {
            return false;
        }
    }
    i = row - 1;
    j = column - 1;
    // 判断正斜对角线是否有冲突
    while (i >= 0 && j >= 0)
    {
        if (arr[i][j])
        {
            return false;
        }
        --i;
        --j;
    }
    i = row - 1;
    j = column + 1;
    // 判断负斜对角线是否有冲突
    while (i >= 0 && j <= ArSize - 1)
    {
        if (arr[i][j])
        {
            return false;
        }
        --i;
        ++j;
    }
    return true;
}
// 打印每种正确的解法
void outPut(bool arr[ArSize][ArSize])
{
    ++num;
    cout << num << endl;
    for (int i = 0; i < ArSize; ++i)
    {
        for (int j = 0; j < ArSize; ++j)
        {
            cout << arr[i][j] << " ";
        }
        cout << endl;
    }
    cout << "*********************************************" << endl;
}

7.30(打印array对象)

#include <iostream> 
#include <iomanip> 
#include <cstdlib>
#include <ctime>
using namespace std;

void printArray( const int [], int, int );

int main()
{
   const int SIZE = 10;
   const int MAXNUMBER = 500;
   int array[ SIZE ];

   srand( time( 0 ) );
   
   for ( int loop = 0; loop < SIZE; loop++ )
      array[ loop ] = 1 + rand() % MAXNUMBER;
   cout << "Array values printed in main:\n"; 
   for ( int j = 0; j < SIZE; j++ )
      cout << setw( 5 ) << array[ j ];
   cout << "\n\nArray values printed in printArray:\n";
   printArray( array, 0, SIZE - 1 );
   cout << endl;
} 

void printArray( const int array[], int low, int high )
{
   cout << setw( 5 ) << array[ low ];
   if ( low == high )
      return;
   else 
      printArray( array, low + 1, high );
}

7.31(逆序打印字符串)

#include <iostream> 
#include <string>
using namespace std;

void stringReverse( string, int );

int main()
{
   string s = "Print this string backward.";
   cout << s << '\n';
   stringReverse( s, 0 );
   cout << endl;
}

void stringReverse( string stringToReverse, int startSubscript )
{
   if ( startSubscript == stringToReverse.length() )
      return;
   stringReverse( stringToReverse, startSubscript + 1 );
   cout << stringToReverse[ startSubscript ];
}

7.32(寻找array对象中的最小值)

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;

const int MAXRANGE = 1000;
int recursiveMinimum( const int [], int, int );

int main()
{
   const int SIZE = 10;
   int array[ SIZE ];
   int smallest;
   srand( time( 0 ) );
   for ( int loop = 0; loop < SIZE; loop++ )
      array[ loop ] = 1 + rand() % MAXRANGE;
   cout << "Array members are:\n";
   for ( int k = 0; k < SIZE; k++ )
      cout << setw( 5 ) << array[ k ];
   cout << '\n';
   smallest = recursiveMinimum( array, 0, SIZE - 1 );
   cout << "\nSmallest element is: " << smallest << endl;
}

int recursiveMinimum( const int array[], int low, int high )
{
   static int smallest = MAXRANGE;
   if ( array[ low ] < smallest )
      smallest = array[ low ];
   return low == high ? 
      smallest : recursiveMinimum( array, low + 1, high );
}

7.33(迷宫遍历)

#include <iostream> 
using namespace std;

enum Direction { DOWN, RIGHT, UP, LEFT };
void mazeTraversal( char [][ 12 ], const int, const int, int, int, int );
void printMaze( const char[][ 12 ] );
bool validMove( const char [][ 12 ], int, int );
bool coordsAreEdge( int, int );

int main()
{
    char maze[12][12] =
    {
    {'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'},
    {'#', '.', '.', '.', '#', '.', '.', '.', '.', '.', '.', '#'},
    {'.', '.', '#', '.', '#', '.', '#', '#', '#', '#', '.', '#'},
    {'#', '#', '#', '.', '#', '.', '.', '.', '.', '#', '.', '#'},
    {'#', '.', '.', '.', '.', '#', '#', '#', '.', '#', '.', '.'},
    {'#', '#', '#', '#', '.', '#', '.', '#', '.', '#', '.', '#'},
    {'#', '.', '.', '#', '.', '#', '.', '#', '.', '#', '.', '#'},
    {'#', '#', '.', '#', '.', '#', '.', '#', '.', '#', '.', '#'},
    {'#', '.', '.', '.', '.', '.', '.', '.', '.', '#', '.', '#'},
    {'#', '#', '#', '#', '#', '#', '.', '#', '#', '#', '.', '#'},
    {'#', '.', '.', '.', '.', '.', '.', '#', '.', '.', '.', '#'},
    {'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'}
    };
   int xStart = 2; // starting X and Y coordinates for maze
   int yStart = 0;
   int x = xStart; // current X and Y coordinates
   int y = yStart;
   mazeTraversal( maze, xStart, yStart, x, y, RIGHT );
}

void mazeTraversal(char maze[][12], const int xStart, const int yStart,
    int xCoord, int yCoord, int direction)
{
    static bool flag = false;
    maze[xCoord][yCoord] = 'x';
    printMaze(maze);
    if (coordsAreEdge(xCoord, yCoord) && xCoord != xStart &&
        yCoord != yStart)
    {
        cout << "\nMaze successfully exited!\n\n";
        return;
    }
    else if (xCoord == xStart && yCoord == yStart && flag)
    {
        cout << "\nArrived back at the starting location.\n\n";
        return;
    }
    else
    {
        flag = true;
        for (int move = direction, count = 0; count < 4; count++,
            move++, move %= 4)
        {
            switch (move)
            {
            case DOWN: // move down
                if (validMove(maze, xCoord + 1, yCoord))
                {
                    mazeTraversal(
                        maze, xStart, yStart, xCoord + 1, yCoord, LEFT);
                    return;
                }
                break;
            case RIGHT: // move right
                if (validMove(maze, xCoord, yCoord + 1))
                {
                    mazeTraversal(
                        maze, xStart, yStart, xCoord, yCoord + 1, DOWN);
                    return;
                }
                break;
            case UP: // move up
                if (validMove(maze, xCoord - 1, yCoord))
                {
                    mazeTraversal(
                        maze, xStart, yStart, xCoord - 1, yCoord, RIGHT);
                    return;
                }
                break;
            case LEFT:
                if (validMove(maze, xCoord, yCoord - 1))
                {
                    mazeTraversal(
                        maze, xStart, yStart, xCoord, yCoord - 1, UP);
                    return;
                }
                break;
            }
        }
    }
}

bool validMove( const char maze[][ 12 ], int r, int c )
{
    return (r >= 0 && r <= 11 && c >= 0 && c <= 11 && maze[r][c] != '#');
}

bool coordsAreEdge( int x, int y )
{
   if ( ( x == 0 || x == 11 ) && ( y >= 0 && y <= 11 ) )
      return true;
   else if ( ( y == 0 || y == 11 ) && ( x >= 0 && x <= 11 ) )
      return true;
   else
      return false;
}

void printMaze( const char maze[][ 12 ] )
{
   for ( int x = 0; x < 12; x++ ) 
   {
      for ( int y = 0; y < 12; y++ )
         cout << maze[ x ][ y ] << ' ';
      cout << '\n';
   }
   cout << "\nHit return to see next move\n";
   cin.get();
}

7.34(随机生成迷宫)

#include <iostream> 
#include <cstdlib>
#include <ctime>
using namespace std;

enum Direction { DOWN, RIGHT, UP, LEFT };
const int MAX_DOTS = 100;

void mazeTraversal(char[][12], const int, const int, int, int, int);
void mazeGenerator(char[][12], int*, int*);
void printMaze(const char[][12]);
bool validMove(const char[][12], int, int);
bool coordsAreEdge(int, int);

int main()
{
    char maze[12][12];
    int xStart; // represent starting coordinates:
    int yStart;
    int x; // current coordinates:
    int y;

    srand(time(0));

    for (int loop = 0; loop < 12; loop++)
        for (int loop2 = 0; loop2 < 12; loop2++)
            maze[loop][loop2] = '#';
    mazeGenerator(maze, &xStart, &yStart); 
    x = xStart;
    y = yStart;
    mazeTraversal(maze, xStart, yStart, x, y, RIGHT);
}

void mazeTraversal(char maze[][12], const int xStart, const int yStart,
    int xCoord, int yCoord, int direction)
{
    static bool flag = false;
    maze[xCoord][yCoord] = 'x';
    printMaze(maze);
    if (coordsAreEdge(xCoord, yCoord) && xCoord != xStart &&
        yCoord != yStart)
    {
        cout << "\nMaze successfully exited!\n\n";
        return;
    }
    else if (xCoord == xStart && yCoord == yStart && flag)
    {
        cout << "\nArrived back at the starting location.\n\n";
        return;
    }
    else
    {
        flag = true;
        for (int move = direction, count = 0; count < 4; count++,
            move++, move %= 4)
        {
            switch (move)
            {
            case DOWN: // move down
                if (validMove(maze, xCoord + 1, yCoord))
                {
                    mazeTraversal(
                        maze, xStart, yStart, xCoord + 1, yCoord, LEFT);
                    return;
                }
                break;
            case RIGHT: // move right
                if (validMove(maze, xCoord, yCoord + 1))
                {
                    mazeTraversal(
                        maze, xStart, yStart, xCoord, yCoord + 1, DOWN);
                    return;
                }
                break;
            case UP: // move up
                if (validMove(maze, xCoord - 1, yCoord))
                {
                    mazeTraversal(
                        maze, xStart, yStart, xCoord - 1, yCoord, RIGHT);
                    return;
                }
                break;
            case LEFT: // move left
                if (validMove(maze, xCoord, yCoord - 1))
                {
                    mazeTraversal(
                        maze, xStart, yStart, xCoord, yCoord - 1, UP);
                    return;
                }
                break;
            }
        }
    }
}

bool validMove(const char maze[][12], int r, int c)
{
    return
        (r >= 0 && r <= 11 && c >= 0 && c <= 11 && maze[r][c] != '#');
}

bool coordsAreEdge(int x, int y)
{
    if ((x == 0 || x == 11) && (y >= 0 && y <= 11))
        return true;
    else if ((y == 0 || y == 11) && (x >= 0 && x <= 11))
        return true;
    else
        return false;
}

void printMaze(const char maze[][12])
{
    for (int x = 0; x < 12; x++)
    {
        for (int y = 0; y < 12; y++)
            cout << maze[x][y] << ' ';

        cout << '\n';
    }

    cout << "\nHit return to see next move\n";
    cin.get();
}

void mazeGenerator(char maze[][12], int* xPtr, int* yPtr)
{
    int a;
    int entry;
    int exit;
    int x;
    int y;
    do
    {
        entry = rand() % 4;
        exit = rand() % 4;
    } while (entry == exit);
    // Determine entry position
    if (entry == 0)
    {
        *xPtr = 1 + rand() % 10; // avoid corners
        *yPtr = 0;
        maze[*xPtr][0] = '.';
    }
    else if (entry == 1)
    {
        *xPtr = 0;
        *yPtr = 1 + rand() % 10;
        maze[0][*yPtr] = '.';
    }
    else if (entry == 2)
    {
        *xPtr = 1 + rand() % 10;
        *yPtr = 11;
        maze[*xPtr][11] = '.';
    }
    else
    {
        *xPtr = 11;
        *yPtr = 1 + rand() % 10;
        maze[11][*yPtr] = '.';
    }

    if (exit == 0)
    {
        a = 1 + rand() % 10;
        maze[a][0] = '.';
    } // end if
    else if (exit == 1)
    {
        a = 1 + rand() % 10;
        maze[0][a] = '.';
    } // end else if
    else if (exit == 2)
    {
        a = 1 + rand() % 10;
        maze[a][11] = '.';
    } // end else if
    else
    {
        a = 1 + rand() % 10;
        maze[11][a] = '.';
    } // end else

    for (int loop = 1; loop < MAX_DOTS; loop++) // add dots randomly
    {
        x = 1 + rand() % 10;
        y = 1 + rand() % 10;
        maze[x][y] = '.';
    } // end for
}