C++ codechef:一款益智游戏

C++ codechef:一款益智游戏,c++,algorithm,depth-first-search,C++,Algorithm,Depth First Search,问题陈述: 约翰尼记小素数有些困难。因此,他的计算机科学老师让他经常玩下面的益智游戏 拼图是一块3x3的板,由1到9的数字组成。拼图的目的是交换瓷砖,直到达到以下最终状态: 1 2 3 4 5 6 7 8 9 在每一步中,约翰尼可能会交换两个相邻的瓷砖,如果它们的总和是一个素数。如果两个瓷砖具有公共边,则认为它们相邻 帮助Johnny找到达到目标状态所需的最短步数 我目前的解决方案 #include<bits/stdc++.h> using namespace std; boo

问题陈述:

约翰尼记小素数有些困难。因此,他的计算机科学老师让他经常玩下面的益智游戏

拼图是一块3x3的板,由1到9的数字组成。拼图的目的是交换瓷砖,直到达到以下最终状态:

1 2 3
4 5 6
7 8 9
在每一步中,约翰尼可能会交换两个相邻的瓷砖,如果它们的总和是一个素数。如果两个瓷砖具有公共边,则认为它们相邻

帮助Johnny找到达到目标状态所需的最短步数

我目前的解决方案

#include<bits/stdc++.h>

using namespace std;

bool prime[20];

int matrix[3][3];
int solved[3][3] = {
    {1,2,3},
    {4,5,6},
    {7,8,9}
};

void display()
{
    for(int row = 0; row<3;row++)
        {
            for(int col = 0;col<3;col++)
            {
                cout<<matrix[row][col]<<" ";
            }
            cout<<endl;
        }
        cout<<endl<<endl;

}

bool check(){
    for(int i=0;i<3;i++){
        for(int j=0;j<3;j++){
            if(matrix[i][j]!=solved[i][j])
                return false;
        }
    }
    return true;
}

int min(int a,int b)
{
    return (a<b)?a:b;
}

void generate(){
    memset(prime,true,sizeof(prime));
    for(int i=2;i*i<20;i++){
        if(prime[i]==true)
        {
            for(int j=2*i;j<20;j+=i)
                prime[j]=false;
        }
    }
}

int getMoves(int row, int col){
    if(row < 0 ||col< 0 || row>=3||col>=3){
        return 0;
    }
    if(check()){
        return 0;
    }

    int moves = 0;

    for(int i = row-1 ; i<= row+1 ;i++)
    {
        for(int j = col -1 ; j<=col+1;j++)
        {
            if((i!=row-1&&j!=col-1)||(i!=row+1&&j!=col+1)||(i!=row+1&&j!=col-1)||(i!=row-1&&j!=col+1)){

                if(prime[matrix[row][col]+matrix[i][j]]==true)
                {
                    moves+=getMoves(i,j);
                    int temp;
                    temp = matrix[i][j];
                    matrix[i][j] = matrix[row][col];
                    matrix[row][col] = temp;
                    display();
                }
            }   
        }
    }
    return moves;
}

int Moves(){
    int minMoves = INF;
    for(int row = 0;row<3;row++)
    {
        for(int col = 0;col<3;col++)
        {
            int moves = getMoves(row,col);
            minMoves = min(moves,minMoves);
        }
    }
    return minMoves;
}



int main(){
    generate();
    int t;
    cin>>t;
    while(t--)
    {
        for(int row = 0; row<3;row++)
        {
            for(int col = 0;col<3;col++)
            {
                cin>>matrix[row][col];
            }
        }

    }
    cout<<Moves();
}

我猜是因为内存溢出问题,程序一直在崩溃。

如果(row<0 | col<0 | row>=3 | row=3 | | col>=3)
恐怕你的代码完全错了,如果不完全重写,我想它是无法修复的。例如,在函数
getMoves()
中,变量
i
j
可以获取值-1,因此您将面临访问冲突错误。其次,这里有一个递归,但在调用递归之前不更改数据。假设您想交换7和4。在下一步中(因为您没有更改输入),您可以交换4和1。但这不是一个正确的举动,因为在那个时候,4不应该出现。第三,您的函数
getMoves()
可能会以无休止的循环结束

if (row < 0 || col< 0 || row >= 3 || row <= 3) {
    return 0;
}
总之,这类问题的解决方式完全不同。您可以使用exmaple,也可以使用。您必须评估您当前的状态。让我们假设以下状态:

7 3 2
4 5 6
1 8 9

您可以测量数字移动到正确位置所需的移动次数。因此,在这种情况下,
1
必须做2个移动,
7
必须做2个移动,
2
必须做1个移动以及数字
3
。此状态的值为
2+2+1+1=6
。这叫做启发式函数。现在您可以使用此函数并将其放入A*算法中,您应该可以看到正确的结果。

不要使用
#include
。永远。现在我明白了。。非常感谢你。。我想我会尝试使用回溯算法来实现。
7 3 2
4 5 6
1 8 9