网易互娱的一道笔试题

题目描述:一张图被裁剪成N行M列,知道每张图片的编号,以及和它上下左右相邻的图片编号,将这张图拼接回去。
输入描述:N(空格)M
接下输入N*M行,每行5个数:第1个数是当前图片的编号,第2个数是当前图片的左边的图片的编号,第3个数是当前图片的上边的图片的编号,第4个数是当前图片的右边的图片的编号,第5个数是当前图片的下边的图片的编号,当相邻的图片没有时,输入0表示。数字与数字之间空格隔开。
如下:

3 3
1 2 4 8 6
2 0 5 1 7
3 4 0 0 8
4 5 0 3 1
5 0 0 4 2
6 7 1 9 0
7 0 2 6 0
8 1 3 0 9
9 6 8 0 0

输出:

5 4 3
2 1 8
7 6 9

输入只是单独得描述了图片的相对位置,但是如果我们想重排,需要知道的是绝对位置。知道一个绝对位置,就可以通过相对位置找到图片的绝对位置。绝对位置就是四个角的位置,第一张图片的左边和上边都没有图片,对应的输入中第1位和第2位为0(从0开始算)。因此需要先找到一个绝对位置(左上角)。找到其他三个角的位置也是一样的。
输入的N*M行的数据保存在二维数组A中:

int n = 3, m = 3;
	//cin >> n >> m;
	int A[NN * MM][5] = { 0 };
	
	int B[NN][MM] = { 0 };
	int num = 0;
	//for (int i = 0; i < n * m; i++) {
	//	for (int j = 0; j < 5; j++) {
	//		cin >> num;
	//		A[i][j] = num;
	//	}
	//}
	A[0][0] = 1;
	A[0][1] = 2;
	A[0][2] = 4;
	A[0][3] = 8;
	A[0][4] = 6;

	A[1][0] = 2;
	A[1][1] = 0;
	A[1][2] = 5;
	A[1][3] = 1;
	A[1][4] = 7;

	A[2][0] = 3;
	A[2][1] = 4;
	A[2][2] = 0;
	A[2][3] = 0;
	A[2][4] = 8;

	A[3][0] = 4;
	A[3][1] = 5;
	A[3][2] = 0;
	A[3][3] = 3;
	A[3][4] = 1;

	A[4][0] = 5;
	A[4][1] = 0;
	A[4][2] = 0;
	A[4][3] = 4;
	A[4][4] = 2;

	A[5][0] = 6;
	A[5][1] = 7;
	A[5][2] = 1;
	A[5][3] = 9;
	A[5][4] = 0;

	A[6][0] = 7;
	A[6][1] = 0;
	A[6][2] = 2;
	A[6][3] = 6;
	A[6][4] = 0;

	A[7][0] = 8;
	A[7][1] = 1;
	A[7][2] = 3;
	A[7][3] = 0;
	A[7][4] = 9;

	A[8][0] = 9;
	A[8][1] = 6;
	A[8][2] = 8;
	A[8][3] = 0;
	A[8][4] = 0;

然后找到左上角的位置:

	int rowA = 0;
	for (int i = 0; i < n * m; i++) {
		if (A[i][1] == 0 && A[i][2] == 0) {
			B[0][0] = A[i][0];
			rowA = i;
			break;
		}
	}

然后根据第一块图片所在的编号为5,A[5-1][3]就是所在的行的下一个格子的图像编号。
找到当前行的第一个图像编号之后,就可以通过一个函数去寻找到当前行的所有图片编号。

void fun_lr(int A[][5], int B[][MM], int rowA, int rowB, int colB) {
	B[rowB][colB] = A[rowA][0];
	if (A[rowA][3] != 0) {
		//右边没有了,当前行找到头了
		fun_lr(A, B, A[rowA][3]-1, rowB, colB+1);
	}
	return;
}

输入中的A[rowA][4]表示当前位置的下一行。如果当前位置还有下一行,那就跳转到下一行。

	for (int i = 0; i < n; i++) {
		fun_lr(A, B, rowA, i, 0);//找完了当前行
		if (A[rowA][4] != 0) {
			rowA = A[rowA][4]-1;//入股当前行还有下一行,换到下一行
		}
	}

完整程序:

#include <iostream>
using namespace std;
#define NN 100
#define MM 100

void fun_lr(int A[][5], int B[][MM], int rowA, int rowB, int colB) {
	B[rowB][colB] = A[rowA][0];
	if (A[rowA][3] != 0) {
		//右边
		fun_lr(A, B, A[rowA][3]-1, rowB, colB+1);
	}
	return;
}


void main9() {
	int n = 3, m = 3;
	//cin >> n >> m;
	int A[NN * MM][5] = { 0 };
	
	int B[NN][MM] = { 0 };
	int num = 0;
	//for (int i = 0; i < n * m; i++) {
	//	for (int j = 0; j < 5; j++) {
	//		cin >> num;
	//		A[i][j] = num;
	//	}
	//}
	A[0][0] = 1;
	A[0][1] = 2;
	A[0][2] = 4;
	A[0][3] = 8;
	A[0][4] = 6;

	A[1][0] = 2;
	A[1][1] = 0;
	A[1][2] = 5;
	A[1][3] = 1;
	A[1][4] = 7;

	A[2][0] = 3;
	A[2][1] = 4;
	A[2][2] = 0;
	A[2][3] = 0;
	A[2][4] = 8;

	A[3][0] = 4;
	A[3][1] = 5;
	A[3][2] = 0;
	A[3][3] = 3;
	A[3][4] = 1;

	A[4][0] = 5;
	A[4][1] = 0;
	A[4][2] = 0;
	A[4][3] = 4;
	A[4][4] = 2;

	A[5][0] = 6;
	A[5][1] = 7;
	A[5][2] = 1;
	A[5][3] = 9;
	A[5][4] = 0;

	A[6][0] = 7;
	A[6][1] = 0;
	A[6][2] = 2;
	A[6][3] = 6;
	A[6][4] = 0;

	A[7][0] = 8;
	A[7][1] = 1;
	A[7][2] = 3;
	A[7][3] = 0;
	A[7][4] = 9;

	A[8][0] = 9;
	A[8][1] = 6;
	A[8][2] = 8;
	A[8][3] = 0;
	A[8][4] = 0;
	int rowA = 0;
	for (int i = 0; i < n * m; i++) {
		if (A[i][1] == 0 && A[i][2] == 0) {
			B[0][0] = A[i][0];
			rowA = i;
			break;
		}
	}
	for (int i = 0; i < n; i++) {
		fun_lr(A, B, rowA, i, 0);
		if (A[rowA][4] != 0) {
			rowA = A[rowA][4]-1;
		}
		
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << B[i][j] << " ";
		}
		cout << endl;
	}
	cout << endl;
	//fun_lr(A, B, rowA-1, 0, 1);
}

int main(void) {
	main9();
	return 0;
}

样例输出:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值