CSAPP bomblab

bomblab

准备工作

  1. 首先我们将目标程序转换成汇编代码写入到bomb.txt方便查看
  2. 然后打开这个文件查看内容

phase_1

在这里插入图片描述
这里我们直接转换成伪c代码:

// 先将栈区减少8
esi = 0x402400;
strings_not_equal(rdi, rsi);
if (eax != 0) {
	explode_bomb();
}
return;
// 恢复栈区

我们可以看到他把0x402400传入到一个strings_not_equal的函数了,那么里面肯定判断的是两个字符串是否相等,不相等就爆炸。所以我们输出0x402400位置的字符串即可。
在这里插入图片描述
第一题答案即为Border relations with Canada have never been better.
在这里插入图片描述

phase_2

在这里插入图片描述
这里我们直接转换成伪c代码:

// stack init
rsi = rbp;
read_six_numbers();
if (*rsp != 1) {
	expoload_bomb();
}
rbx = rsp + 4;
rbp = rsp + 20;
400f17:
eax = *(rbx - 4);
eax = eax + eax;
if (*rbx != eax) {
	expload_bomb();
}
rbx += 4;
if (rbx != rbp) {
	jmp 400f17;
}
// stack init

首先我们在分析一下read_six_numbers():
在这里插入图片描述我们发现esi中存的是0x4025c3,我们将这个内存地址指向的东西输出:
在这里插入图片描述
发现是六个数。
然后我们分析phase_2:
rbx是读入的第二个数,rbp是读入的最后一个数,首先我们判断读入的第一个数是否是1,如果不是爆炸,是的话我们比较后一项是否是前一项的两倍,如果不是也爆炸,所以最后我们得出的结果是:

  1. 一共六个数,读入的第一个数是1
  2. 每一个数是前面的数的两倍

即答案为1 2 4 8 16 32
在这里插入图片描述

phase_3

0000000000400f43 <phase_3>:
  400f43:       48 83 ec 18             sub    $0x18,%rsp
  400f47:       48 8d 4c 24 0c          lea    0xc(%rsp),%rcx
  400f4c:       48 8d 54 24 08          lea    0x8(%rsp),%rdx
  400f51:       be cf 25 40 00          mov    $0x4025cf,%esi
  400f56:       b8 00 00 00 00          mov    $0x0,%eax
  400f5b:       e8 90 fc ff ff          call   400bf0 <__isoc99_sscanf@plt>
  400f60:       83 f8 01                cmp    $0x1,%eax
  400f63:       7f 05                   jg     400f6a <phase_3+0x27>
  400f65:       e8 d0 04 00 00          call   40143a <explode_bomb>
  400f6a:       83 7c 24 08 07          cmpl   $0x7,0x8(%rsp)
  400f6f:       77 3c                   ja     400fad <phase_3+0x6a>
  400f71:       8b 44 24 08             mov    0x8(%rsp),%eax
  400f75:       ff 24 c5 70 24 40 00    jmp    *0x402470(,%rax,8)
  400f7c:       b8 cf 00 00 00          mov    $0xcf,%eax
  400f81:       eb 3b                   jmp    400fbe <phase_3+0x7b>
  400f83:       b8 c3 02 00 00          mov    $0x2c3,%eax
  400f88:       eb 34                   jmp    400fbe <phase_3+0x7b>
  400f8a:       b8 00 01 00 00          mov    $0x100,%eax
  400f8f:       eb 2d                   jmp    400fbe <phase_3+0x7b>
  400f91:       b8 85 01 00 00          mov    $0x185,%eax
  400f96:       eb 26                   jmp    400fbe <phase_3+0x7b>
   400f98:       b8 ce 00 00 00          mov    $0xce,%eax
  400f9d:       eb 1f                   jmp    400fbe <phase_3+0x7b>
  400f9f:       b8 aa 02 00 00          mov    $0x2aa,%eax
  400fa4:       eb 18                   jmp    400fbe <phase_3+0x7b>
  400fa6:       b8 47 01 00 00          mov    $0x147,%eax
  400fab:       eb 11                   jmp    400fbe <phase_3+0x7b>
  400fad:       e8 88 04 00 00          call   40143a <explode_bomb>
  400fb2:       b8 00 00 00 00          mov    $0x0,%eax
  400fb7:       eb 05                   jmp    400fbe <phase_3+0x7b>
  400fb9:       b8 37 01 00 00          mov    $0x137,%eax
  400fbe:       3b 44 24 0c             cmp    0xc(%rsp),%eax
  400fc2:       74 05                   je     400fc9 <phase_3+0x86>
  400fc4:       e8 71 04 00 00          call   40143a <explode_bomb>
  400fc9:       48 83 c4 18             add    $0x18,%rsp
  400fcd:       c3                      ret

这里我们直接转换成伪c代码:

// stack init
rcx = rsp + 12;
rdx = rsp + 8;
esi = 0x4025cf; 
eax = 0;
__isoc99_sscanf@plt();
if (eax <= 1) {
	expload_bomb();
}
if (*(rsp + 8) > 7) {
	jmp 400fad;
}
eax = *(rsp + 8);
jmp *0x402470(, %rax, 8);
switch {
	case 0:
		eax = 0xcf;
		break;
	case 2:
		eax = 0x2c3;
		break;
	case 3:
		eax = 0x100;
		break;
	case 4:
		eax = 0x185;
		break;
	case 5:
		eax = 0xce;
		break;
	case 6:
		eax = 0x2aa;
		break;
	case 7:
		eax = 0x147;
		break;
	case 1:
		eax = 0x137;
		break;
}
400fad:
explode_bomb();
eax = 0;
if (eax != *(rsp + 12)) {
	explode_bomb();
}
// stack init

首先我们看一下esi中指向的内容,发现我们需要输入的应该是两个整数
在这里插入图片描述
其次,根据

  400f75:       ff 24 c5 70 24 40 00    jmp    *0x402470(,%rax,8)

我们可以知道这里应该是switch case 语句,所以我们需要去找每个跳转语句的条件,我们输出出来一一对应
在这里插入图片描述
发现如果我们输入的第一个数和eax的关系:

0  0xcf 
1  0x137 
2  0x2c3 
3  0x100
4  0x185 
5  0xce
6  0x2aa 
7  0x147 

所以我们要确保输入的第一个数和他得到的eax与输入的第二个数相同,即答案可以是

0 207 
1 311 
2 707
3 256 
4 389 
5 206 
6 682 
7 327

在这里插入图片描述

phase_4

0000000000400fce <func4>:
  400fce:       48 83 ec 08             sub    $0x8,%rsp
  400fd2:       89 d0                   mov    %edx,%eax
  400fd4:       29 f0                   sub    %esi,%eax
  400fd6:       89 c1                   mov    %eax,%ecx
  400fd8:       c1 e9 1f                shr    $0x1f,%ecx
  400fdb:       01 c8                   add    %ecx,%eax
  400fdd:       d1 f8                   sar    %eax
  400fdf:       8d 0c 30                lea    (%rax,%rsi,1),%ecx
  400fe2:       39 f9                   cmp    %edi,%ecx
  400fe4:       7e 0c                   jle    400ff2 <func4+0x24>
  400fe6:       8d 51 ff                lea    -0x1(%rcx),%edx
  400fe9:       e8 e0 ff ff ff          call   400fce <func4>
  400fee:       01 c0                   add    %eax,%eax
  400ff0:       eb 15                   jmp    401007 <func4+0x39>
  400ff2:       b8 00 00 00 00          mov    $0x0,%eax
  400ff7:       39 f9                   cmp    %edi,%ecx
  400ff9:       7d 0c                   jge    401007 <func4+0x39>
  400ffb:       8d 71 01                lea    0x1(%rcx),%esi
  400ffe:       e8 cb ff ff ff          call   400fce <func4>
  401003:       8d 44 00 01             lea    0x1(%rax,%rax,1),%eax
  401007:       48 83 c4 08             add    $0x8,%rsp
  40100b:       c3                      ret

000000000040100c <phase_4>:
  40100c:       48 83 ec 18             sub    $0x18,%rsp
  401010:       48 8d 4c 24 0c          lea    0xc(%rsp),%rcx
  401015:       48 8d 54 24 08          lea    0x8(%rsp),%rdx
  40101a:       be cf 25 40 00          mov    $0x4025cf,%esi
  40101f:       b8 00 00 00 00          mov    $0x0,%eax
  401024:       e8 c7 fb ff ff          call   400bf0 <__isoc99_sscanf@plt>
  401029:       83 f8 02                cmp    $0x2,%eax
  40102c:       75 07                   jne    401035 <phase_4+0x29>
  40102e:       83 7c 24 08 0e          cmpl   $0xe,0x8(%rsp)
  401033:       76 05                   jbe    40103a <phase_4+0x2e>
  401035:       e8 00 04 00 00          call   40143a <explode_bomb>
  40103a:       ba 0e 00 00 00          mov    $0xe,%edx
  40103f:       be 00 00 00 00          mov    $0x0,%esi
  401044:       8b 7c 24 08             mov    0x8(%rsp),%edi
  401048:       e8 81 ff ff ff          call   400fce <func4>
  40104d:       85 c0                   test   %eax,%eax
  40104f:       75 07                   jne    401058 <phase_4+0x4c>
  401051:       83 7c 24 0c 00          cmpl   $0x0,0xc(%rsp)
  401056:       74 05                   je     40105d <phase_4+0x51>
  401058:       e8 dd 03 00 00          call   40143a <explode_bomb>
  40105d:       48 83 c4 18             add    $0x18,%rsp
  401061:       c3                      ret

这里我们直接转换成伪c代码:

func4(rdi, rsi, rdx) {
	// stack init
	eax = edx;
	eax -= esi;
	eax = ecx;
	ecx >>= 31;
	eax += ecx;
	eax >>= 1;
	ecx = rax + rsi + 1;
	if (ecx <= edi) {
		jmp 400ff2;
	}
	edx = rcx - 1;
	func4(rdi, rsi, rdx)
	eax = eax + eax;
	jmp 401007;
	eax = 0;
400ff2:
	if (ecx >= edi) {
		jmp 4010007;
	}
	esi = rcx + 1;
	func4(rdi, rsi, rdx);
	eax = eax + eax + 1;
401007:
	// stack init
}

phase_4(){
	//stack init 
	rcx = rsp + 12;
	rdx = rsp + 8;
	esi = 0x4025cf;
	eax = 0;
	__isoc99_sscanf@plt();
	if (eax != 2) {
		expload_bomb();
	}
	else if (*(rsp + 8) > 14) {
		expload_bomb();
	}
	edx = 14;
	esi = 0;
	edi = *(rsp + 8);
	func4(rdi, rsi, rdx);
	if (eax != 0) {
		expload_bomb();
	}
	else if (*(rsp + 12) != 0) {
		expload_bomb();
	}
	// stack init
}

这里我们可以再化简下fun4()

func4(int val, int l, int r) {
	m = (r - l + (r - l) >> 31) >> 1; 
	c = m + l;
	if (c < val) {
		return 2 * func4(val, l, m - 1) + 1;
	} 
	else if (c > val) {
		return 2 * func4(val, l + 1, m);
	}
	else {
		return 0;
	}
}

我们可以看出fun4其实就是二分查找,那么对于phase_4,我们需要查找的是我们输入的第一个数,查找的左右边界为0,14,最后我们要得到的结果是eax为0,那么我们可以知道,最后找到的时候返回值为0,所以往上几层每一层都要是往左走,所以得到的答案可以是

7 0 
3 0 
1 0
0 0

在这里插入图片描述

phase_5

0000000000401062 <phase_5>:
  401062:       53                      push   %rbx
  401063:       48 83 ec 20             sub    $0x20,%rsp
  401067:       48 89 fb                mov    %rdi,%rbx
  40106a:       64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
  401071:       00 00
  401073:       48 89 44 24 18          mov    %rax,0x18(%rsp)
  401078:       31 c0                   xor    %eax,%eax
  40107a:       e8 9c 02 00 00          call   40131b <string_length>
  40107f:       83 f8 06                cmp    $0x6,%eax
  401082:       74 4e                   je     4010d2 <phase_5+0x70>
  401084:       e8 b1 03 00 00          call   40143a <explode_bomb>
  401089:       eb 47                   jmp    4010d2 <phase_5+0x70>
  40108b:       0f b6 0c 03             movzbl (%rbx,%rax,1),%ecx
  40108f:       88 0c 24                mov    %cl,(%rsp)
  401092:       48 8b 14 24             mov    (%rsp),%rdx
  401096:       83 e2 0f                and    $0xf,%edx
  401099:       0f b6 92 b0 24 40 00    movzbl 0x4024b0(%rdx),%edx
  4010a0:       88 54 04 10             mov    %dl,0x10(%rsp,%rax,1)
  4010a4:       48 83 c0 01             add    $0x1,%rax
  4010a8:       48 83 f8 06             cmp    $0x6,%rax
  4010ac:       75 dd                   jne    40108b <phase_5+0x29>
  4010ae:       c6 44 24 16 00          movb   $0x0,0x16(%rsp)
  4010b3:       be 5e 24 40 00          mov    $0x40245e,%esi
  4010b8:       48 8d 7c 24 10          lea    0x10(%rsp),%rdi
  4010bd:       e8 76 02 00 00          call   401338 <strings_not_equal>
  4010c2:       85 c0                   test   %eax,%eax
  4010c4:       74 13                   je     4010d9 <phase_5+0x77>
  4010c6:       e8 6f 03 00 00          call   40143a <explode_bomb>
  4010cb:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
  4010d0:       eb 07                   jmp    4010d9 <phase_5+0x77>
  4010d2:       b8 00 00 00 00          mov    $0x0,%eax
  4010d7:       eb b2                   jmp    40108b <phase_5+0x29>
  4010d9:       48 8b 44 24 18          mov    0x18(%rsp),%rax
  4010de:       64 48 33 04 25 28 00    xor    %fs:0x28,%rax
  4010e5:       00 00
  4010e7:       74 05                   je     4010ee <phase_5+0x8c>
  4010e9:       e8 42 fa ff ff          call   400b30 <__stack_chk_fail@plt>
  4010ee:       48 83 c4 20             add    $0x20,%rsp
  4010f2:       5b                      pop    %rbx
  4010f3:       c3                      ret

这里我们直接转换成伪c代码:

// stack init
rbx = rdi;
rax = fs:0x28 (金丝雀值,这里可以看书上的定义)
*(rsp + 24) = rax;
eax ^= eax;
eax = string_length();
if (eax != 6) {
	expload_bomb();
}
jmp 4010d2;
40108b:
ecx = rax + rbx;
*rsp = cl;
rdx = *rsp;
edx &= 0xf;
edx = *(rdx + 0x4024b0);
*(rsp + rax + 16) = dl;
rax += 1;
if (rax != 6) {
	jmp 40108b;
}
*(rsp + 22) = 0;
esi = 0x40245e;
rdi = rsp + 16;
string_not_equal(rdi, rsi);
if (eax == 0) {
	jmp 4010d9;
}
explode_bomb();
jmp 4010d9;
4010d2:
eax = 0;
jmp 40108b;
4010d9:
rax = *(rsp + 24);
if (rax != fs:0x28) {
	__stack_chk_fail@plt();
} // 输入的字符串导致金丝雀值发生改变
// stack init

化简一下可以得到:

// stack init
rbx = rdi;
rax = fs:0x28 // 金丝雀值,这里可以看书上的定义
*(rsp + 24) = rax;
eax ^= eax;
eax = string_length();
if (eax != 6) {
	expload_bomb();
}
for (rax = 0; rax != 6; rax++) {
	ecx = rax + rbx; // rdi + rax
	*rsp = cl; // 取出字符
	rdx = *rsp; 
	edx &= 0xf; // 把字符的ascii和0xf按位与
	edx = *(rdx + 0x4024b0); // 
	*(rsp + rax + 16) = dl; // 将字符放到rsp + rax + 16的位置上
}
*(rsp + 22) = 0; // 字符串结尾
esi = 0x40245e;
rdi = rsp + 16;
string_not_equal(rdi, rsi); // 最后得到的rdi要和rsi相同
if (eax != 0) {
	explode_bomb();
}
rax = *(rsp + 24);
if (rax != fs:0x28) {
	__stack_chk_fail@plt();
} // 输入的字符串导致金丝雀值发生改变
// stack init

首先我们将rsi代表的字符串找出来:
在这里插入图片描述然后我们将重心放到循环内部,我们可以看到就是取输入的字符串的每一个字符与0xf按位与后再放到栈中,后面要使得按位与后的字符组成的字符串为"flyers",直接查阅ascii码,发现有很多答案,我们取其中一个即可。
答案:ionefg
在这里插入图片描述

phase_6

00000000004010f4 <phase_6>:
  4010f4:	41 56                	push   %r14
  4010f6:	41 55                	push   %r13
  4010f8:	41 54                	push   %r12
  4010fa:	55                   	push   %rbp
  4010fb:	53                   	push   %rbx
  4010fc:	48 83 ec 50          	sub    $0x50,%rsp
  401100:	49 89 e5             	mov    %rsp,%r13
  401103:	48 89 e6             	mov    %rsp,%rsi
  401106:	e8 51 03 00 00       	call   40145c <read_six_numbers>
  40110b:	49 89 e6             	mov    %rsp,%r14
  40110e:	41 bc 00 00 00 00    	mov    $0x0,%r12d
  401114:	4c 89 ed             	mov    %r13,%rbp
  401117:	41 8b 45 00          	mov    0x0(%r13),%eax
  40111b:	83 e8 01             	sub    $0x1,%eax
  40111e:	83 f8 05             	cmp    $0x5,%eax
  401121:	76 05                	jbe    401128 <phase_6+0x34>
  401123:	e8 12 03 00 00       	call   40143a <explode_bomb>
  401128:	41 83 c4 01          	add    $0x1,%r12d
  40112c:	41 83 fc 06          	cmp    $0x6,%r12d
  401130:	74 21                	je     401153 <phase_6+0x5f>
  401132:	44 89 e3             	mov    %r12d,%ebx
  401135:	48 63 c3             	movslq %ebx,%rax
  401138:	8b 04 84             	mov    (%rsp,%rax,4),%eax
  40113b:	39 45 00             	cmp    %eax,0x0(%rbp)
  40113e:	75 05                	jne    401145 <phase_6+0x51>
  401140:	e8 f5 02 00 00       	call   40143a <explode_bomb>
  401145:	83 c3 01             	add    $0x1,%ebx
  401148:	83 fb 05             	cmp    $0x5,%ebx
  40114b:	7e e8                	jle    401135 <phase_6+0x41>
  40114d:	49 83 c5 04          	add    $0x4,%r13
  401151:	eb c1                	jmp    401114 <phase_6+0x20>
  401153:	48 8d 74 24 18       	lea    0x18(%rsp),%rsi
  401158:	4c 89 f0             	mov    %r14,%rax
  40115b:	b9 07 00 00 00       	mov    $0x7,%ecx
  401160:	89 ca                	mov    %ecx,%edx
  401162:	2b 10                	sub    (%rax),%edx
  401164:	89 10                	mov    %edx,(%rax)
  401166:	48 83 c0 04          	add    $0x4,%rax
  40116a:	48 39 f0             	cmp    %rsi,%rax
  40116d:	75 f1                	jne    401160 <phase_6+0x6c>
  40116f:	be 00 00 00 00       	mov    $0x0,%esi
  401174:	eb 21                	jmp    401197 <phase_6+0xa3>
  401176:	48 8b 52 08          	mov    0x8(%rdx),%rdx
  40117a:	83 c0 01             	add    $0x1,%eax
  40117d:	39 c8                	cmp    %ecx,%eax
  40117f:	75 f5                	jne    401176 <phase_6+0x82>
  401181:	eb 05                	jmp    401188 <phase_6+0x94>
  401183:	ba d0 32 60 00       	mov    $0x6032d0,%edx
  401188:	48 89 54 74 20       	mov    %rdx,0x20(%rsp,%rsi,2)
  40118d:	48 83 c6 04          	add    $0x4,%rsi
  401191:	48 83 fe 18          	cmp    $0x18,%rsi
  401195:	74 14                	je     4011ab <phase_6+0xb7>
  401197:	8b 0c 34             	mov    (%rsp,%rsi,1),%ecx
  40119a:	83 f9 01             	cmp    $0x1,%ecx
  40119d:	7e e4                	jle    401183 <phase_6+0x8f>
  40119f:	b8 01 00 00 00       	mov    $0x1,%eax
  4011a4:	ba d0 32 60 00       	mov    $0x6032d0,%edx
  4011a9:	eb cb                	jmp    401176 <phase_6+0x82>
  4011ab:	48 8b 5c 24 20       	mov    0x20(%rsp),%rbx
  4011b0:	48 8d 44 24 28       	lea    0x28(%rsp),%rax
  4011b5:	48 8d 74 24 50       	lea    0x50(%rsp),%rsi
  4011ba:	48 89 d9             	mov    %rbx,%rcx
  4011bd:	48 8b 10             	mov    (%rax),%rdx
  4011c0:	48 89 51 08          	mov    %rdx,0x8(%rcx)
  4011c4:	48 83 c0 08          	add    $0x8,%rax
  4011c8:	48 39 f0             	cmp    %rsi,%rax
  4011cb:	74 05                	je     4011d2 <phase_6+0xde>
  4011cd:	48 89 d1             	mov    %rdx,%rcx
  4011d0:	eb eb                	jmp    4011bd <phase_6+0xc9>
  4011d2:	48 c7 42 08 00 00 00 	movq   $0x0,0x8(%rdx)
  4011d9:	00 
  4011da:	bd 05 00 00 00       	mov    $0x5,%ebp
  4011df:	48 8b 43 08          	mov    0x8(%rbx),%rax
  4011e3:	8b 00                	mov    (%rax),%eax
  4011e5:	39 03                	cmp    %eax,(%rbx)
  4011e7:	7d 05                	jge    4011ee <phase_6+0xfa>
  4011e9:	e8 4c 02 00 00       	call   40143a <explode_bomb>
  4011ee:	48 8b 5b 08          	mov    0x8(%rbx),%rbx
  4011f2:	83 ed 01             	sub    $0x1,%ebp
  4011f5:	75 e8                	jne    4011df <phase_6+0xeb>
  4011f7:	48 83 c4 50          	add    $0x50,%rsp
  4011fb:	5b                   	pop    %rbx
  4011fc:	5d                   	pop    %rbp
  4011fd:	41 5c                	pop    %r12
  4011ff:	41 5d                	pop    %r13
  401201:	41 5e                	pop    %r14
  401203:	c3                   	ret    

我们先写出伪c代码:

phase_6(){
	// stack init
	r13 = rsp;
	rsi = rsp;
	read_six_numbers(rdi, rsi);
	r14 = rsp;
	for (r12d = 0; r12d != 6; r12d++) {
		rbp = r13;
		eax = *r13;
		eax -= 1;
		if (eax > 5) {
			explode_bomb();
		}
		for (ebx = r12d + 1; ebx <= 5; ebx++) {
				rax = ebx;
				eax = *(rsp + 4rax);
				if (*rbp == eax)
				{
					explode_bomb();
				}		
		}
		r13 += 4;
	}
	// 这一个循环是判断每个数是否都小于6并且每个数都不能相等
	rsi = rsp + 24;
	rax = r14;
	ecx = 7;
	for (rax = r14; rax != rsi; rax += 4) {
		edx = ecx;
		edx -= *rax;
		*rax = edx;
	}
	// 这个循环是将每个数x都变为7 - x
	for (rsi = 0; rsi != 24; rsi+=4) {
		ecx = *(rsp + rsi);
		edx = 0x6032d0;
		if(ecx > 1) {
			for (eax = 1; eax != ecx; eax++) {
				rdx = *(rdx+8); 
			}
		}
		*(rsp + 2 * rsi + 32) = rdx;
	}
	// 这个循环是取每个数如果这个数大于1那么edx = edx + 8
	// 然后将得到的edx赋给内存的一块区域,可以看到区域的大小应该为8
	rbx = *(rsp + 32);
	// 这个就是第一个edx存放的地方
	rcx = rbx;
	for (rax = rsp + 40; rax != rsi + 80; rax += 8){
		rdx = *rax;
		*(rcx + 8) = rdx;
		rcx = rdx;
	}
	// 这个循环是将rbx+8的指向*rax
	*(rdx + 8) = 0;
	for (ebp = 5; ebp != 0; ebp--) {
		rax = *(rbx + 8);
		eax = *rax;
		if (eax < *rbx) {
			explode_bomb();
		}
		rbx = *(rbx + 8);
	}
	// 这个循环是在比较rbx + 8和rbx的大小,如果和位置相反则爆炸
	// stack init
}

再优化:

void phase_6(char* output)
{
    int array[6];
    ListNode* node_array[6];
    read_six_numbers(output, array);
    // 数字范围必须为1-6且互不重复
    for (int i = 0; i != 6; i++) {
        int num = array[i];
        num--;
        if ((unsigned int)num > 5)		// 最大为6
            explode_bomb();
        for (int j = i+1; j <= 5; j++) {
            if (array[i] == array[j])	// 每个元素都不重复
                explode_bomb();
        }
    }
    // 修改 array
	for (int i = 0; i < 6; i ++) {
        array[i] = (7 - array[i]);
	}
    // 生成 node_array
	for (int i = 0; i < 6; i ++) {
        int cur = array[i];
        ListNode* node = 0x6032d0;		// 链表head
        if (cur > 1) {
            for (int j = 1; j < cur; j++) {
                node = node->next;
            }
        }
        node_array[i] = node;
	}
    for (int i = 0; i < 5; i++) {
        node_array[i]->next = node_array[i+1];
    }
    ListNode* ptr = node_array[0];
    for (int i = 5; i > 0; i--) {
        if (ptr->val < ptr->next->val)
            explode_bomb();
        ptr = ptr->next;
    }
}

在这里插入图片描述
从这里看,从大到小应该是345612,我们要使得最后链表的值递减,所以应该输入432165,然后转换后为345612,将第三个安排在第一位,第四个安排在第二位…
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值