2D matrix - splitting the matrix in two parts with equal number of elements The elements in the matrix are either 'M', 'G', 'P' or '.' and the algorith must write out all possible ways of splitting the matrix so it has equal number of M, G and P on each side. It's a task we've been given to do at home. We also had to use use the matrix as a parameter in the function and use it as a pointer in it. What would you change to make it more optimized?

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int field_split(char *k, int r, int s, int *ptrP, int *ptrG, int *ptrM){
    int i, j, numberP = 0, numberG = 0, numberM = 0;
    int splitNumber = 0;
    int tmpP = 0, tmpG = 0, tmpM = 0;

    for (i = 0; i &lt; r*s; i ++){
        switch(k[i]){
            case 'P':
                numberP ++;
                break;
            case 'M':
                numberM ++;
                break;
            case 'G':
                numberG ++;
                break;
        }
    }

    for (i = 0; i &lt; r; i++){
        for (j = 0; j &lt; s; j ++){
            switch(k[i * s + j]){
                case 'P':
                    tmpP ++;
                    break;
                case 'M':
                    tmpM ++;
                    break;
                case 'G':
                    tmpG ++;
                    break;
            }
        }
        if(tmpP == numberP / 2 &amp;&amp; tmpM == numberM / 2 &amp;&amp; tmpG == numberG / 2)
            splitNumber ++;
    }

    tmpP = tmpM = tmpG = 0;

    for (j = 0; j &lt; s; j++){
        for (i = 0; i &lt; r; i ++){
            switch(k[i * s + j]){
                case 'P':
                    tmpP ++;
                    break;
                case 'M':
                    tmpM ++;
                    break;
                case 'G':
                    tmpG ++;
                    break;
            }
        }
        if(tmpP == numberP / 2 &amp;&amp; tmpM == numberM / 2 &amp;&amp; tmpG == numberG / 2)
            splitNumber ++;
    }

    *ptrP = numberP;
    *ptrG = numberG;
    *ptrM = numberM;

    return splitNumber;
}

int main()
{
    int r, s, i, j;
    int splitNumber;
    int numberP, numberM, numberG;
    int tmpP = 0, tmpM = 0, tmpG = 0;
    int count = 1;

    scanf("%d %d", &amp;r, &amp;s);
    char field[r][s];

    for (i = 0; i &lt; r; i ++){
        for(j = 0; j &lt; s; j ++)
            scanf(" %c", &amp;field[i][j]);
    }

    splitNumber = field_split(&amp;field[0][0], r, s, &amp;numberP, &amp;numberG, &amp;numberM);

    if (splitNumber &gt; 0 ){

        printf("Ways of splitting the field: %d", splitNumber);

        for (i = 0; i &lt; r; i ++){
            for(j = 0; j &lt; s; j ++){
                switch(field[i][j]){
                    case 'P':
                        tmpP ++;
                        break;
                    case 'G':
                        tmpG ++;
                        break;
                    case 'M':
                        tmpM ++;
                        break;
                }
            }
            if(tmpP == numberP / 2 &amp;&amp; tmpG == numberG / 2 &amp;&amp; tmpM == numberM / 2){
                printf("\n%d. Horizontally, between row  %d and %d", count, i + 1, i + 2);
                count ++;
            }
        }

        tmpP = tmpG = tmpM = 0;

        for (j = 0; j &lt; s; j ++){
            for(i = 0; i &lt; r; i ++){
                switch(field[i][j]){
                    case 'P':
                        tmpP ++;
                        break;
                    case 'G':
                        tmpG ++;
                        break;
                    case 'M':
                        tmpM ++;
                        break;
                }
            }
            if(tmpP == numberP / 2 &amp;&amp; tmpG == numberG / 2 &amp;&amp; tmpM == numberM / 2){
                printf("\n%d. Vertically, between column %d and %d", count, j + 1, j + 2);
                count++;
            }
        }
    }

    else
        printf("Can't be split 50-50.");

    return 0;
}
Bug
If there are an odd number of M, P, or G, it should be impossible to split the matrix in half.  However, your program may erroneously think it is possible because of this type of comparison:

tmpP == numberP / 2


which can be true for example if tmpP == 2 and numberP == 5, due to the division rounding down.  Here is an example input that demonstrates this:
3 3
M M M
M M S
S P S

An easy way to fix this would be to compare like this instead:
tmpP * 2 == numberP

which doesn't suffer from any roundoff errors.  Or you could immediately return 0 possibilities if any of the three counts is odd.
Repetitive code
Your code in field_split() seems reasonable, and there isn't much that can be improved there.  However, you created a nearly exact duplicate of your code in main().  Perhaps you did this because you needed to print the total count of the answers before printing each individual answer.
A better alternative would be to generate the answers in field_split() and return them to main().  Then you could print the count of answers followed by each individual answer.  You not only reduce your code by half, you also don't have to traverse your matrix twice.
Sample rewrite
Here is how I would rewrite your code.  Some things I did:

Use helper functions to handle repetitive tasks.
Return all the ways the matrix can be split directly from field_split() to avoid having to traverse the matrix twice.
Short circuit the function if any of the counts are odd.
Cleaned up the printing code to add the proper newlines.
Added const keyword to k argument which is not modified by field_split().
Cleaned up spacing which was inconsistent in a few places.

The rewrite:
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;stdbool.h&gt;

#define MAX_SYMBOLS        3

// Counts GMP and adds to symCount[]
static void countSymbol(char symbol, int *symCount)
{
    switch (symbol) {
        case 'G':
            symCount[0]++;
            break;
        case 'M':
            symCount[1]++;
            break;
        case 'P':
            symCount[2]++;
            break;
    }
}

// Returns true if each count in curCount is half the count in totCount.
static bool isHalf(int *curCount, int *totCount)
{
    int i;

    for (i = 0; i &lt; MAX_SYMBOLS; i++) {
        if (curCount[i] * 2 != totCount[i])
            return false;
    }
    return true;
}

// Returns the number of ways the matrix can be split horizontally or
// vertically, with each side having half of each symbol.
//
// WaysHorizontal must be an array of at least (columns-1) size.
// WaysVertical   must be array of at least (rows-1) size.
static int field_split(const char *k, int rows, int columns,
        int *pNumHorizontal, int *waysHorizontal, int *pNumVertical,
        int *waysVertical)
{
    int i                     = 0;
    int j                     = 0;
    int totSize               = rows * columns;
    int totCount[MAX_SYMBOLS] = {0};
    int curCount[MAX_SYMBOLS] = {0};
    int numHorizontal         = 0;
    int numVertical           = 0;

    // First count all the symbols.
    for (i = 0; i &lt; totSize; i++) {
        countSymbol(k[i], totCount);
    }

    // If any count is odd, there are no answers.
    for (i = 0; i &lt; MAX_SYMBOLS; i++) {
        if (totCount[i] &amp; 1) {
            *pNumHorizontal = 0;
            *pNumVertical   = 0;
            return 0;
        }
    }

    // Find horizontal splits.
    for (i = 0; i &lt; rows - 1; i++) {
        for (j = 0; j &lt; columns; j++) {
            countSymbol(k[i*columns + j], curCount);
        }
        if (isHalf(curCount, totCount)) {
            waysHorizontal[numHorizontal++] = i;
        }
    }

    // Find vertical splits.
    memset(curCount, 0, sizeof(curCount));
    for (j = 0; j &lt; columns - 1; j++) {
        for (i = 0; i &lt; rows; i++) {
            countSymbol(k[i*columns + j], curCount);
        }
        if (isHalf(curCount, totCount)) {
            waysVertical[numVertical++] = j;
        }
    }

    *pNumHorizontal = numHorizontal;
    *pNumVertical   = numVertical;
    return numHorizontal + numVertical;
}

int main(void)
{
    int rows, columns, i, j;
    int splitNumber;

    scanf(&quot;%d %d&quot;, &amp;rows, &amp;columns);

    char field[rows][columns];
    int waysHorizontal[columns];
    int waysVertical[rows];
    int numHorizontal;
    int numVertical;
    int totalSplits;

    for (i = 0; i &lt; rows; i++) {
        for (j = 0; j &lt; columns; j++) {
            scanf(&quot; %c&quot;, &amp;field[i][j]);
        }
    }

    totalSplits = field_split(&amp;field[0][0], rows, columns, &amp;numHorizontal,
                    waysHorizontal, &amp;numVertical, waysVertical);

    if (totalSplits &gt; 0) {
        int splitIndex = 1;

        printf(&quot;Ways of splitting the field: %d\n&quot;, totalSplits);
        for (i = 0; i &lt; numHorizontal; i++) {
            printf(&quot;%d. Horizontally, between row %d and %d\n&quot;, splitIndex++,
                    waysHorizontal[i]+1, waysHorizontal[i]+2);
        }
        for (i = 0; i &lt; numVertical; i++) {
            printf(&quot;%d. Vertically, between column %d and %d\n&quot;, splitIndex++,
                    waysVertical[i]+1, waysVertical[i]+2);
        }
    } else {
        printf(&quot;Can't be split 50-50.\n&quot;);
    }

    return 0;
}