与按升序排序二维数组相关的拼图

时间:2015-10-15 09:59:33

标签: c++ arrays sorting

向用户提供随机生成的4x4 2-D数组,其中一个元素肯定为0.考虑到0为空位置,用户必须重复交换剩余的15个元素,直到他们得到数组按升序排列,最后一个元素为0。 此时,他们允许用0交换任何元素。 但是,如何修改此代码以确保只能将那些与0相邻的元素(在其上方,下方或旁边)交换?

#include<iostream>
#include<stdlib.h>
#include<time.h>

using namespace std;

int check_asc(int a[][4])
{ 
int i, j, previous = a[0][0];

for (i = 0; i < 4; i++)
{
    for (j = 0; j < 4; j++)
    {
        if(i == 3 && j == 3)
        {
            if (a[i][j] == 0)
                return 1;
        }
        else if (a[i][j] < previous)
        {
            return 0;
        }
        previous = a[i][j];
    }
}
return 1;
}

void swap(int a[][4], int &xpos, int &ypos)
{
int arr, temp;

cout << "\n\nEnter number to be swapped with 0: ";
cin >> arr;

for (int i = 0; i < 4; i++)
{
    for (int j = 0; j < 4; j++)
    {
        if (a[i][j] == arr)
        {
            temp = a[xpos][ypos];
            a[xpos][ypos] = a[i][j];
            a[i][j] = temp;
            xpos = i;
            ypos = j;
            return;
        }
    }
}
}

int check_rep(int a[][4], int assign)
{
for (int i = 0; i < 4; i++)
{
    for (int j = 0; j < 4; j++)
    {
        if (assign == a[i][j])
        return 0;
    }
}
return 1;
}

void main()
{
int a[4][4], assign, xpos = 0, ypos = 0, asc_result, rep_result;

srand((unsigned)time(NULL));

for (int i = 0; i < 4; i++)
    for (int j = 0; j < 4; j++)
    {
        if (i == 0 && j == 0)
            a[i][j] = 0;
        else
        {
            do {
                assign = rand() % 50;
                rep_result = check_rep(a, assign);
            } while (rep_result == 0);
            a[i][j] = assign;
        }
    }

    cout << "\n\nArrange the 4x4 matrix into ascending order. (Consider 0 as a blank space)" << endl;

    for (int i = 0; i < 4; i++)
    {
    cout << endl;
    for (int j = 0; j < 4; j++)
        cout << a[i][j] << '\t';
    }

    do {
        swap(a, xpos, ypos);
        system("cls");

        for (int i = 0; i < 4; i++)
        {
        cout << endl;
        for (int j = 0; j < 4; j++)
            cout << a[i][j] << '\t';
        }
        asc_result = check_asc(a);

    } while (asc_result == 0);

    cout << "\n\tYou win"<<endl;

    system("pause");
}

2 个答案:

答案 0 :(得分:1)

简单,只需用一段代码扩展你的交换函数,该代码将检查要交换的元素的位置是否与0的位置相邻:

    void swap(int a[][4], int &xpos, int &ypos)
    {
    ...
        if (a[i][j] == arr &&
              ((i == xpos && (j == ypos - 1 || j == ypos + 1)) ||
               (j == ypos && (i == xpos - 1 || i == xpos + 1))))
        {
            temp = a[xpos][ypos];
            a[xpos][ypos] = a[i][j];
            a[i][j] = temp;
            xpos = i;
            ypos = j;
            return;
        }

改进是分离检查条件,并在元素不与0相邻时通知用户。

答案 1 :(得分:0)

粗略算法

1)创建一个函数查找位置,它将返回一个结构具有x,y整数字段的Point,它将根据pieces值找到任何一块的x,y位置,即假设输入0,如果它位于左上角(0,0),将返回一个点(0,0)

2)创建一个接收2个点的函数,'0'的位置和我们希望交换的部分的位置让我们称之为S,如果Sx = 0.x且0.y - 1 = Sy或Sy - 0.y + 1然后你就知道所说的那块直接位于0的上方或下方,现在当然你没有为边界添加一些条件,所以我们不在网格之外检查。如果S部分位于上/下/旁边,则此函数返回int 1,否则返回0。

3)如果1返回你允许翻转,如果返回0则找到另一个