因此,这是一个每周上学的项目,并且我已经使其完全正常工作,但是感觉好像我做的那样,可能不是最好的方法之一(甚至不是一个好方法)。我希望你们可以帮助优化它/提供更好的解决方案。我已经提交了此版本,但想知道一个更优化的解决方案。

首先,这就是问题所在...

输入示例:

10 10
pzzzzzzzzp
pyypzzzzzy
ppppssssyy
ssspssssyy
ssssppssyy
ssssppsspy
zzzzzzsspy
zzzzzzsspy
yyyypzsspy
yyyypppppy
3 4
pppp
pppp
pppp
1 7
zzzzzzz
0 0

示例输出:
Garden # 1: 4 patches, sizes: 1 4 8 10
Garden # 2: 1 patches, sizes: 12
Garden # 3: 0 patches, sizes:
注意:即使问题出在输入文件,我们的教授还是告诉我们通过键盘输入。

我的方法是将花园变成2d数组,并在其周围带有x的边界。然后,我将使用一个函数来查找南瓜补丁(并返回其坐标)。然后,我将使用另一个函数,该函数以递归方式找到南瓜是否通过上,下,左,右连接到该南瓜,并返回南瓜补丁的大小。当找到南瓜时,此功能还可以通过将其替换为“x”来“删除”每个南瓜。这使我不必担心多次发现南瓜。
因此,这是我的代码,经过了很好的注释,以便您可以希望理解我正在尝试做的事情。
#include <iostream>
#include <fstream>

using namespace std;

const int MAX_ROW = 41;
const int MAX_COL = 41;

char input ();

int checkForPatchSize ( char arr[][MAX_COL], int numOne, int numTwo );

bool findPatch ( char arr[][MAX_COL], int &row, int&col );

void sort ( int arr[], int size);

int main ()
    {
    int inputNumOne = -1;  // Defaulted to -1, First number for Patch Size
    int inputNumTwo = -1;  // Defaulted to -1, Second number for Patch Size
    int i, j;      // i, j are indexes for loops, number
    int numArr[MAX_ROW][MAX_COL]; // Array for storing Data
    int indexGarden = 0;
    int index = 1;

    while ( inputNumOne != 0 )
        {
        cin >> inputNumOne;       // User inputs Dimension
        cin >> inputNumTwo;       // Of Garden...
        if ( inputNumOne != 0 and inputNumTwo != 0 )   // End case is that both are 0.
            {
            char pumpkinPatch[MAX_ROW][MAX_COL];   // Array for storing pumpkin patch info.
            for ( i = 0; i < inputNumOne+2; i++ )
                {
                for ( j = 0; j < inputNumTwo+2; j++ )
                     {
                    // This if statement surrounds the garden in X's so that I have a border (allows me to not have to worry about test cases.
                    if ( i == 0 or j == 0 or i == inputNumOne + 1 or j == inputNumTwo + 1 )
                        {
                        pumpkinPatch[i][j] = 'x';
                        }
                    else   // This is the input of the garden into a 2d array.
                        {
                        pumpkinPatch[i][j] = input();
                        }
                    }

                }




            int row, col, size, numberOfPatches = 0;
            bool foundPatch = true;
            index = 1;

            while ( foundPatch == true )
                {
                row = inputNumOne+2;  // Because I added a border to the garden
                col = inputNumTwo+2;  // the size is +2 of what the user input.
                foundPatch = findPatch ( pumpkinPatch, row, col );  // Finds the start of a pumpkin patch, and returns the coordinates ( as row and col ).
                if ( foundPatch == true ) // If a patch is found....
                    {
                    numberOfPatches++;  // Increase number of patches
                    size = checkForPatchSize ( pumpkinPatch, row, col); // find size of particular patch
                    numArr[indexGarden][index] = size; // put size into data arr (to be printed to screen later).
                    index++;


                    }

                }
                numArr[indexGarden][0] = numberOfPatches; // Put number of patches as first item in each column of data arr.
                indexGarden++;


            }

        }

    for ( index = 0; index < indexGarden; index++ ) // Print out Garden Info
        {
        cout << "Garden # " << index + 1 <<": " << numArr[index][0] << " patches, sizes: ";
        int temp = numArr[index][0]; // temp is the number of patches in particular garden.
        int tempArr[temp];   // temp array to be used for sorting
        int indexTwo;
        for ( indexTwo = 0; indexTwo < temp; indexTwo++ )
            {
            tempArr[indexTwo] = numArr[index][indexTwo+1];   // Transfer sizes into a temp array so that they can be sorted.

            }
        sort (tempArr, temp);  // Sort ( Sorts arr from smalles to larges )

        for ( indexTwo = 0; indexTwo < temp; indexTwo++ )  // Output sorted array to screen.
            {
            cout << tempArr[indexTwo] << " ";
            }

        cout << endl;
       }






    }

char input()
   {
    char letter;
    cin >> letter;
    return letter;
    }
/////////////// findPatch /////////////////////////////////////////////////
// Requirements: a 2D array of garden, and the size of it (row and col). //
// Returns a bool, true if patch is found, false if no patches found.    //
// row and col are returned by reference to be the coordinates of one    //
//  of the pumpkins in the patch.                                    //
///////////////////////////////////////////////////////////////////////////
bool findPatch ( char arr[][MAX_COL], int &row, int&col )
    {
    int rowIndex = 0;
int colIndex = 0;

while ( arr[rowIndex][colIndex] != 'p' and rowIndex < row )
    {
    colIndex = 0;
    while ( arr[rowIndex][colIndex] != 'p' and colIndex < col )
        {
        colIndex++;
        }
    if ( arr[rowIndex][colIndex] != 'p' )
        {
        rowIndex++;
        }
    }

if ( arr[rowIndex][colIndex] != 'p' )
    {
    return false;
    }
row = rowIndex;
col = colIndex;
return true;

}

/////////////// checkForPatchSize /////////////////////////////////////////
// Requirements: a 2D array of garden, and the coordinates of the start  //
//                 of a patch.  (Gotten from findPatch)                  //
// Returns an int, which is the size of the patch found                  //
// All p's or pumpkins are changed to x's so that they are not used      //
//  multiple times.                                                  //
///////////////////////////////////////////////////////////////////////////
int checkForPatchSize ( char arr[][MAX_COL], int numOne, int numTwo )
{
int index = 0;


if ( arr[numOne][numTwo] == 'p' )
    {
    index++;
    arr[numOne][numTwo] = '0';

        // Check Above
        index += checkForPatchSize ( arr, numOne - 1, numTwo );

        // Check to Left
        index += checkForPatchSize ( arr, numOne, numTwo - 1 );

        // Check Below
        index += checkForPatchSize ( arr, numOne + 1, numTwo );

        // Check to Right
        index += checkForPatchSize ( arr, numOne, numTwo + 1 );

    return index;
    }

return 0;





}
/////////////// sort //////////////////////////////////////////////////////
// Requirements: an integer array, and the size of it (amount of         //
//               numbers in it).                                         //
//                                                                       //
// Sorts an array from smalles to largest numbers                        //
///////////////////////////////////////////////////////////////////////////
void sort ( int arr[], int size )
{
int index = 0;
bool changeMade = true;

while ( changeMade == true )
    {
    changeMade = false;
    for ( index = 0; index < size - 1; index++ )
        {
        if ( arr[index] > arr[index+1] )
            {
            int temp = arr[index];
            arr[index] = arr[index+1];
            arr[index+1] = temp;
            changeMade = true;
            }
        }

    }
}

最佳答案

好了,阅读完您的代码后,我会看到您的方法。通常,我会从视觉 Angular 解决这个问题。实际上,您的代码应该可以正常工作,并且是一个非常优雅的解决方案。该算法的唯一缺点是,每次移动时都会在同一补丁上进行迭代。例如,当它向上移动时,它向下检查。避免冗余是最佳算法的最可靠标志,但是就您部署算法的规模而言,它不一定是最佳的。

在某种程度上,您的代码的递归性质使其非常漂亮,因为它遍历南瓜补丁,就像消失的小 Spark 一样,我真的很喜欢。递归是我不常打扰的事情,主要是因为我不递归地思考,但是花了一些时间将头放在算法周围,在这种情况下,我确实看到了它的值(value)。我很想看到该算法与动态视觉效果一起工作。

至于您算法的准确性,我无法想象它将无法以任何方式正确地计算南瓜数,因为它的作用是围绕拾取的南瓜绕一小波,算法在其中重复自身,从而有效传播通过补丁直到它全部算在内。就像我说的那样,您的算法的唯一缺点是,如果您不以某种方式将南瓜标记为已发现(它将检查从其调用的位置),它将陷入无限循环。除此之外,我只能说您已经提出了一个很好的解决方案,并且您的疑虑几乎完全是错误的。在这方面,使用递归算法是一个很好的选择,因为它不需要很长的案例列表就可以进行“计数”。它只是跳到相邻位置,并以全部计数返回自身。

关于c++ - 优化 “It'的“大南瓜补丁”。” ACM 1999练习,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18995129/

10-12 21:06