点击上方“iOS开发”,选择“置顶公众号”
关键时刻,第一时间送达!
效果图
一、准备工作
先了解一个定义和定理
定义:在一个1,2,...,n的排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。逆序数为偶数的排列称为偶排列;逆序数为奇数的排列称为奇排列。如2431中,21,43,41,31是逆序,逆序数是4,为偶排列。——这是北大《高等代数》上的定义。
定理:交换一个排列中的两个数,则排列的奇偶性发生改变。
二、实现过程
以3*3拼图为例进行分析
1、随机打乱拼图
1)初始化从0-8的数组initializeNums
NSMutableArray *initializeNums = [NSMutableArray array];//初始化0-n数字
for (int i = 0; i < _puzzleCount; i++) {
[initializeNums addObject:@(i)];
}
2)从initializeNums随机抽取数字add到数组randomNums,得到随机数组
NSMutableArray *randomNums = [NSMutableArray array];//随机数组
for (int i = 0; i < _puzzleCount; i++) {
int randomNum = arc4random() % initializeNums.count;
[randomNums addObject:initializeNums[randomNum]];
[initializeNums removeObjectAtIndex:randomNum];
}
3)判断拼图是否可还原
① 图1,通过移动要还原到的拼图状态
② 图2,随机打乱的拼图状态
③ 图3,将图2中的空白块移动到拼图右下角的拼图状态,用来计算打乱的拼图是否可以还原
④ 空白块处相当于数字8
⑤ 我们的目的是把打乱拼图如图2通过移动(空白块与相邻数字块位置交换)还原到图1状态
⑥ 不是每个随机打乱的拼图都能还原到图1状态(根据定义和定理有50%概率随机打乱的拼图不能还原)
⑦ 根据定义和定理 ,图1的逆序数为0,为偶排列。所以只有图3也为偶排列,图2才有可能还原到图1状态
图1
图2
如何计算图3的逆序数
① 先计算图2的逆序数
② 再计算图2到图3变换步数
③ 将两者相加即得图3逆序数
图3
判断图2是否可还原代码:
//判断是否可还原拼图
inverCount = 0;
int curNum = 0;
int nextNum = 0;