1 条题解
-
0
问题理解
我们需要模拟一个类似于“十五数码拼图”的游戏,但可以支持任意大小的网格(R行S列)。游戏的初始状态是一个R×S的网格,其中包含编号为1到R×S-1的方块和一个空格(用0表示)。玩家可以通过移动与空格相邻的方块(上、下、左、右)来改变拼图的状态。我们的任务是:
读取输入,包括多个测试用例。 对于每个测试用例: 读取拼图的初始状态(R行S列的数字矩阵)。 读取一系列移动指令,每个指令是一个方块编号T。 对于每个移动指令: 检查方块T是否可以移动到空格的位置(即方块T是否与空格相邻)。 如果可以移动,执行移动并输出相应的移动信息(如“Kamen T presunut doprava.”)。 如果不能移动,输出“Neplatny tah kamenem T.”。 在所有移动完成后,输出拼图的最终状态。 每个测试用例之间用空行分隔。
解决思路
输入处理: 首先读取测试用例的数量Z。 对于每个测试用例:读取R和S(网格的行数和列数)。 读取R行,每行包含S个数字,表示初始拼图状态。我们需要将这些数字存储在一个二维数组中,并记录空格的位置(即值为0的单元格的坐标)。 读取移动指令,直到遇到0为止。 移动处理: 对于每个移动指令T: 找到编号为T的方块的位置(i, j)。 检查空格是否与方块T相邻(即空格的位置是否在(i-1,j)、(i+1,j)、(i,j-1)、(i,j+1)之一)。 如果相邻,交换方块T和空格的位置,更新空格的位置,并输出相应的移动信息。 如果不相邻,输出无效移动信息。 输出处理: 在所有移动完成后,按照指定的格式输出拼图的最终状态(每行S个数字,用单个空格分隔)。 在每个测试用例之间输出一个空行。
代码实现
#include <iostream> #include <cstdio> #include <algorithm> #include <string> using namespace std; int da[1010][1010]; int dx[4]={-1,1,0,0}; int dy[4]={0,0,-1,1}; string nam[4]={"dolu","nahoru","doprava", "doleva" }; int main() { int T; cin>>T; int tag=0; while(T--) { tag++; int n,m; cin>>n>>m; int oi,oj; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { cin>>da[i][j]; if(da[i][j]==0) { oi=i; oj=j; } } } cout<<"Skladacka cislo "<<tag<<":"<<endl; while(1) { int x; cin>>x; if(x==0) { break; } int flag=0; for(int i=0;i<4;i++) { int tx=oi+dx[i]; int ty=oj+dy[i]; if(tx>=0 &&tx<n && ty>=0 && ty<m) { if(da[tx][ty]==x) { swap(da[oi][oj],da[tx][ty]); oi=tx; oj=ty; flag=1; cout<<"Kamen "<<x<<" presunut "<<nam[i]<<"."<<endl; break; } } } if(flag==0) { cout<<"Neplatny tah kamenem "<<x<<"."<<endl; } } for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { cout<<da[i][j]<<" "; } cout<<endl; } cout<<endl; } return 0; }
- 1
信息
- ID
- 999
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者