• 飞机大作战(c语言)


       前言:

    飞机大作战游戏是一种非常受欢迎的射击类游戏,玩家需要控制一架战斗机在屏幕上移动,击落敌机以获得分数。本游戏使用C语言编写,旨在帮助初学者了解游戏开发的基本概念和技巧。

    在开始编写代码之前,我们需要先了解一下游戏的基本规则和功能:

    1. 游戏界面:游戏界面是一个矩形区域,玩家可以在这个区域内控制战斗机移动和射击。

    2. 战斗机:玩家控制的战斗机可以在游戏界面内自由移动,按下特定键可以发射子弹和开启技能击落敌机。

    3. 敌机:敌机会从屏幕的一侧出现,并沿着直线路径向另一侧移动。玩家需要击落敌机以获得分数。

    4. 分数:玩家每击落一架敌机,分数会增加。

    5. 游戏结束:当玩家飞机被敌机撞到到或者得分为0时,游戏结束。

    接下来,我们将通过以下几个步骤来实现这个游戏:

    1. 初始化游戏界面和战斗机。

    2. 处理键盘输入,实现战斗机的移动和射击。

    3. 生成敌机,并控制其移动。

    4. 检测战斗机与敌机之间的碰撞,更新分数和技能充能值。

    5. 判断游戏是否结束。

    通过学习这个游戏的开发过程,初学者将能够掌握C语言编程的基本技巧。

    1. 打印菜单:

    1. void menu()
    2. {
    3. printf("--------------飞机大作战--------------\n");
    4. printf("| |\n");
    5. printf("| 1.开始游戏 |\n");
    6. printf("| 0.退出游戏 |\n");
    7. printf("| W/A/S/D移动 |\n");
    8. printf("| 空格射击 E/R技能 |\n");
    9. printf("| |\n");
    10. printf("--------------------------------------\n");
    11. }
    12. int main()
    13. {
    14. system("color b");
    15. int input = 0;
    16. menu();
    17. printf("请选择:");
    18. scanf("%d", &input);
    19. switch (input)
    20. {
    21. case 1:
    22. game();
    23. break;
    24. case 0:
    25. printf("退出游戏\n");
    26. break;
    27. default:
    28. printf("输入有误,请重新输入:\n");
    29. break;
    30. }
    31. return 0;
    32. }

    2. 写一个存放信息的数组

    	int arr[Col][Row] = { 0 };
    

    3. 写一个打印数组信息的函数

    飞机大作战的要素无非就是路、围墙、玩家飞机、敌机、子弹这五个元素,要想在打印出这几个元素,我们只需在写一个函数在二维数组中存放这个五个元素的信息(用0-4代替),然后再写一个打印信息的函数分别出二维数组中对应的信息。

    1. void DisPlay(int arr[Col][Row])
    2. {
    3. gotoxy(0, 0);
    4. for(int i=0;i
    5. {
    6. for (int j = 0; j < Row; j++)
    7. {
    8. if (arr[i][j] == 0)
    9. {
    10. printf(" ");
    11. }
    12. if (arr[i][j] == 1)
    13. {
    14. printf("█");
    15. }
    16. if (arr[i][j] == 2)
    17. {
    18. printf("*");
    19. }
    20. if (arr[i][j] == 3)
    21. {
    22. printf("$");
    23. }
    24. if (arr[i][j] == 4)
    25. {
    26. printf("|");
    27. }
    28. }
    29. printf("\n");
    30. }
    31. printf("得分:%d ", score);
    32. printf("EnemySleep=%d ", EnemySleep);
    33. printf("skill1(20)=%d ", skill1);
    34. printf("skill2(5)=%d ", skill2);
    35. Sleep(20);
    36. }

    4. 写一个函数来初始化数组的信息

    1. void InSet(int arr[Col][Row])
    2. {
    3. //路--0
    4. //墙--1
    5. //玩家飞机--2
    6. //敌机--3
    7. //子弹--4
    8. }

    5. 初始化围墙

    数组最边边的位置我们都让它等于1,这样就可以把游戏界面围起来了。

    1. //墙--1
    2. for (int i = 0; i < Col; i++)
    3. {
    4. arr[i][0] = 1;
    5. arr[i][Row - 1] = 1;
    6. }
    7. for (int i = 0; i < Row; i++)
    8. {
    9. arr[0][i] = 1;
    10. arr[Col - 1][i] = 1;
    11. }

    6. 初始化玩家飞机

    玩家飞机刚开始应该出现在下侧的中央位置,所以将这个位置的坐标对应的值初始化为2。

    1. //玩家飞机--2
    2. arr[PlayerPlane_y][PlayerPlane_x] = 2;

    7. 玩家操作飞机

    通过按下A/W/S/D键来控制飞机的移动,空格键来控制飞机发射子弹,要想实现这个功能我们需要用到getch()函数,这个函数用于从标准输入(通常是键盘)获取一个字符,而不需要用户按下回车键。这个函数在Windows操作系统下的conio.h头文件中定义,而在Unix/Linux系统下,通常使用termios.hunistd.h头文件中的函数来实现类似的功能。

    1. char ch = getch();
    2. if (ch == 'w' && arr[PlayerPlane_y - 1][PlayerPlane_x] == 0)
    3. {
    4. arr[PlayerPlane_y][PlayerPlane_x] = 0;
    5. PlayerPlane_y--;
    6. arr[PlayerPlane_y][PlayerPlane_x] = 2;
    7. }
    8. if (ch == 'a' && arr[PlayerPlane_y][PlayerPlane_x - 1] == 0)
    9. {
    10. arr[PlayerPlane_y][PlayerPlane_x] = 0;
    11. PlayerPlane_x--;
    12. arr[PlayerPlane_y][PlayerPlane_x] = 2;
    13. }
    14. if (ch == 's' && arr[PlayerPlane_y + 1][PlayerPlane_x] == 0)
    15. {
    16. arr[PlayerPlane_y][PlayerPlane_x] = 0;
    17. PlayerPlane_y++;
    18. arr[PlayerPlane_y][PlayerPlane_x] = 2;
    19. }
    20. if (ch == 'd' && arr[PlayerPlane_y][PlayerPlane_x + 1] == 0)
    21. {
    22. arr[PlayerPlane_y][PlayerPlane_x] = 0;
    23. PlayerPlane_x++;
    24. arr[PlayerPlane_y][PlayerPlane_x] = 2;
    25. }
    26. if (ch == ' ')
    27. {
    28. Bullet_y = PlayerPlane_y - 1;
    29. Bullet_x = PlayerPlane_x;
    30. arr[Bullet_y][Bullet_x] = 4;
    31. }
    32. }

    8. 子弹上移

    子弹上移一格就调用一次DisPlay函数打印内容这样就实现了子弹上移的效果,这时需要用到到我们的while循环来循环子弹上移的函数和打印的函数,而子弹是由玩家按键产生的,所以这个while还需要循环上玩家操作飞机的函数,但是getch()会让while停止下来,玩家按键后才会继续,导致玩家按一次键盘按键,子弹才会上移一次,样就子弹就出现不了的这连续上移的效果了,所以我们需要在玩家操作的函数加上if(_kbhit())的判断语句函数,它会判断是否有按键按下来,如果没有就不执行getch()函数,继续循环。

    _kbhit() 是一个C语言中的函数,用于检测键盘是否有按键被按下。它通常在Windows操作系统下的conio.h头文件中定义。该函数不接受任何参数,并返回一个整数值。如果键盘上有按键被按下,则返回非零值(通常是1),否则返回0。

    1. while (1)
    2. {
    3. //玩家操作
    4. PlayerPlay(arr);
    5. //打印棋盘
    6. DisPlay(arr);
    7. //子弹与敌机的操作
    8. BulletEnemy(arr);
    9. }

    在循环打印的时候它会框框打印根本就看不清游戏界面,所以在这里还需要使用到光标的知识 :

    在C语言中,光标通常指的是控制台或终端中的文本输入位置指示器。它显示了用户当前输入或输出的位置。在编写C程序时,有时需要对光标的显示和位置进行控制,以便创建更复杂的用户界面或处理特定的输入输出需求。

    在Windows操作系统下,可以使用conio.h头文件中提供的函数来控制光标。

    因为它会在光标的位置输出信息,所以我们在每次打印前将光标的位置置为(0,0)就可以了。

    但是光标还会在那框框的闪,非常的碍眼,所以我们还需要使用函数将光标隐藏。

    1. void HideCursor()
    2. {
    3. CONSOLE_CURSOR_INFO cursor_info = { 1,0 }; //第二个值为0,表示隐藏光标
    4. SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
    5. }

    9. 初始化敌机

    在这里我们需要随机生成5架敌机出现在游戏界面上侧1-3格的位置,所以需要使用一个大小为5的数组接受随机数的值。

    1. //敌机--3
    2. for (int i = 0; i < Count; i++)
    3. {
    4. Enemy_y[i] = rand() % 3 + 1;
    5. Enemy_x[i] = rand() % Row + 1;
    6. //防止敌机生成在围墙上
    7. if (Enemy_x[i] >= Row - 1)
    8. Enemy_x[i] -= 2;
    9. arr[Enemy_y[i]][Enemy_x[i]] = 3;
    10. }

    10. 敌机的下移

    如果敌机也像子弹一样直接进去循环的话,那么敌机会移动得非常快,所以我们需要定义两个全局变量sleep和EnemySleep来控制敌机的移动速度,例如给EnemySleep赋值一个20,然后sleep赋值一个0,随后sleep在while循环中循环一次就加1,当sleep等于EnemySleep时我们才给敌机进行一次下移的操作,这样就相当于while每循环20次,敌机才下移一次。

    在敌机下的过程中我们可能无法打中敌机,而使敌机下降到了最下侧,这时就得让敌机在触碰到围墙前一格消失,然后重新在上侧生成新的敌机。

    在敌机下移的过程中可能会碰到玩家的飞机,这时游戏就得结束了,然后告诉玩家游戏结束。控制游戏结束需要用到system("pause")和exit()这两个函数。

    system("pause")的作用是在Windows系统的命令行窗口中暂停程序的执行,等待用户按下任意键后继续执行。这通常用于调试程序时,以便查看程序运行过程中的输出结果。

    exit(0);是C/C++语言中用于终止程序执行的语句。其中,参数0表示程序正常退出,非零值表示程序异常退出。在程序执行到该语句时,程序会立即停止运行,并返回给操作系统一个退出状态码。

    1. //控制敌机的速度
    2. if (sleep < EnemySleep)
    3. {
    4. sleep++;
    5. }
    6. else if (sleep > EnemySleep)
    7. {
    8. sleep = 0;
    9. }
    10. for (int i = 0; i < Count; i++)
    11. {
    12. //敌机击中玩家飞机的处理
    13. if (PlayerPlane_y == Enemy_y[i] && PlayerPlane_x == Enemy_x[i] || score < 0)
    14. {
    15. printf(" /\\_/\\ \n");
    16. printf(" ( o.o ) \n");
    17. printf(" > ^ < \n");
    18. printf("游戏失败!\n");
    19. printf("\a");
    20. system("pause");
    21. exit(0);
    22. }
    23. //敌机到达最底面的处理
    24. if (Enemy_y[i] >= Col - 2)
    25. {
    26. score -= 100;
    27. arr[Enemy_y[i]][Enemy_x[i]] = 0;
    28. Enemy_y[i] = rand() % 3 + 1;
    29. Enemy_x[i] = rand() % Row + 1;
    30. if (Enemy_x[i] >= Row - 1)
    31. Enemy_x[i] -= 2;
    32. arr[Enemy_y[i]][Enemy_x[i]] = 3;
    33. }
    34. //敌机下移的处理
    35. if (sleep == EnemySleep)
    36. {
    37. for (int j = 0; j < Count; j++)
    38. {
    39. arr[Enemy_y[j]][Enemy_x[j]] = 0;
    40. sleep = 0;
    41. Enemy_y[j]++;
    42. arr[Enemy_y[j]][Enemy_x[j]] = 3;
    43. }
    44. }
    45. }

     11. 游戏数值的设定

    (1)敌机加速的分数阈值

    • 当玩家得分达到 2000 分时,敌机的移动速度增加 2
    • 当玩家得分再次增加 2000 分,即达到 4000 分时,敌机的移动速度再增加 2
    • 以此类推,每当玩家得分增加 2000 分,敌机的速度增加 2

    (2)打爆一架敌机的得分

    • 打爆一架普通敌机,玩家得到 100 分。

    (3)一架敌机到底部消失的失分

    • 如果一架敌机到达屏幕底部而未被击落,玩家失去 100 分。

    12. 游戏的优化

    为了使游戏更具可玩性,我们可以给玩家飞机加上一些技能,在这里的我设定了E/R是释放技能的指令,这个加在玩家操作飞机的函数哪里就可以了,这两个技能都是可发射范围更广的子弹,当然了这两个技能也不是无限释放的,是需要达到一定的值才能释放的,这里我们可以设定一个变量来存放一个技能的充能值,打爆一架敌机就给充能值加1,当这个值达到的我们所规定的满能值时才能接受释放技能的指令。

    1. //技能指令
    2. if (ch == 'r')
    3. {
    4. if (skill1 == 20)
    5. {
    6. for (int i = 1; i < Row - 1; i++)
    7. {
    8. skill1 = 0;
    9. Bullet_y = PlayerPlane_y - 1;
    10. Bullet_x = i;
    11. arr[Bullet_y][Bullet_x] = 4;
    12. }
    13. }
    14. }
    15. if (ch == 'e')
    16. {
    17. int left = PlayerPlane_x - 3;
    18. int right = PlayerPlane_x + 3;
    19. if (skill2 == 5)
    20. {
    21. for (int i = left; i < right; i++)
    22. {
    23. if (i > 0 && i < Row - 1)
    24. {
    25. skill2 = 0;
    26. Bullet_y = PlayerPlane_y - 1;
    27. Bullet_x = i;
    28. arr[Bullet_y][Bullet_x] = 4;
    29. }
    30. }
    31. }
    32. }

    源码: 

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #define Count 5
    8. #define Col 40//列
    9. #define Row 40//行
    10. //玩家飞机坐标
    11. int PlayerPlane_y = Col - 2;
    12. int PlayerPlane_x = Row / 2 - 1;
    13. //子弹坐标
    14. int Bullet_y;
    15. int Bullet_x;
    16. //敌机坐标
    17. int Enemy_y[Count] = { 0 };
    18. int Enemy_x[Count] = { 0 };
    19. //敌机的移动速度
    20. int EnemySleep = 20;
    21. int sleep = 0;
    22. //分数
    23. int score = 0;
    24. //技能充能
    25. int skill1 = 20;
    26. int skill2 = 5;
    27. void menu()
    28. {
    29. printf("--------------飞机大作战--------------\n");
    30. printf("| |\n");
    31. printf("| 1.开始游戏 |\n");
    32. printf("| 0.退出游戏 |\n");
    33. printf("| W/A/S/D移动 |\n");
    34. printf("| 空格射击 E/R技能 |\n");
    35. printf("| |\n");
    36. printf("--------------------------------------\n");
    37. }
    38. //隐藏光标
    39. void HideCursor()
    40. {
    41. CONSOLE_CURSOR_INFO cursor_info = { 1,0 }; //第二个值为0,表示隐藏光标
    42. SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
    43. }
    44. // 光标移到(X, Y)位置
    45. void gotoxy(int x, int y)
    46. {
    47. HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    48. COORD pos;
    49. pos.X = x;
    50. pos.Y = y;
    51. SetConsoleCursorPosition(handle, pos);
    52. }
    53. void DisPlay(int arr[Col][Row])
    54. {
    55. gotoxy(0, 0);
    56. for(int i=0;i
    57. {
    58. for (int j = 0; j < Row; j++)
    59. {
    60. if (arr[i][j] == 0)
    61. {
    62. printf(" ");
    63. }
    64. if (arr[i][j] == 1)
    65. {
    66. printf("█");
    67. }
    68. if (arr[i][j] == 2)
    69. {
    70. printf("*");
    71. }
    72. if (arr[i][j] == 3)
    73. {
    74. printf("$");
    75. }
    76. if (arr[i][j] == 4)
    77. {
    78. printf("|");
    79. }
    80. }
    81. printf("\n");
    82. }
    83. printf("得分:%d ", score);
    84. printf("EnemySleep=%d ", EnemySleep);
    85. printf("skill1(20)=%d ", skill1);
    86. printf("skill2(5)=%d ", skill2);
    87. Sleep(20);
    88. }
    89. void InSet(int arr[Col][Row])
    90. {
    91. srand(time(NULL));
    92. //路--0
    93. //墙--1
    94. for (int i = 0; i < Col; i++)
    95. {
    96. arr[i][0] = 1;
    97. arr[i][Row - 1] = 1;
    98. }
    99. for (int i = 0; i < Row; i++)
    100. {
    101. arr[0][i] = 1;
    102. arr[Col - 1][i] = 1;
    103. }
    104. //玩家飞机--2
    105. arr[PlayerPlane_y][PlayerPlane_x] = 2;
    106. //敌机--3
    107. for (int i = 0; i < Count; i++)
    108. {
    109. Enemy_y[i] = rand() % 3 + 1;
    110. Enemy_x[i] = rand() % Row + 1;
    111. if (Enemy_x[i] >= Row - 1)
    112. Enemy_x[i] -= 2;
    113. arr[Enemy_y[i]][Enemy_x[i]] = 3;
    114. }
    115. //子弹--4
    116. }
    117. void PlayerPlay(int arr[Col][Row])
    118. {
    119. if (_kbhit())//判断是否有按键按下
    120. {
    121. char ch = getch();
    122. if (ch == 'w' && arr[PlayerPlane_y - 1][PlayerPlane_x] == 0)
    123. {
    124. arr[PlayerPlane_y][PlayerPlane_x] = 0;
    125. PlayerPlane_y--;
    126. arr[PlayerPlane_y][PlayerPlane_x] = 2;
    127. }
    128. if (ch == 'a' && arr[PlayerPlane_y][PlayerPlane_x - 1] == 0)
    129. {
    130. arr[PlayerPlane_y][PlayerPlane_x] = 0;
    131. PlayerPlane_x--;
    132. arr[PlayerPlane_y][PlayerPlane_x] = 2;
    133. }
    134. if (ch == 's' && arr[PlayerPlane_y + 1][PlayerPlane_x] == 0)
    135. {
    136. arr[PlayerPlane_y][PlayerPlane_x] = 0;
    137. PlayerPlane_y++;
    138. arr[PlayerPlane_y][PlayerPlane_x] = 2;
    139. }
    140. if (ch == 'd' && arr[PlayerPlane_y][PlayerPlane_x + 1] == 0)
    141. {
    142. arr[PlayerPlane_y][PlayerPlane_x] = 0;
    143. PlayerPlane_x++;
    144. arr[PlayerPlane_y][PlayerPlane_x] = 2;
    145. }
    146. if (ch == ' ')
    147. {
    148. Bullet_y = PlayerPlane_y - 1;
    149. Bullet_x = PlayerPlane_x;
    150. arr[Bullet_y][Bullet_x] = 4;
    151. }
    152. if (ch == 'r')
    153. {
    154. if (skill1 == 20)
    155. {
    156. for (int i = 1; i < Row - 1; i++)
    157. {
    158. skill1 = 0;
    159. Bullet_y = PlayerPlane_y - 1;
    160. Bullet_x = i;
    161. arr[Bullet_y][Bullet_x] = 4;
    162. }
    163. }
    164. }
    165. if (ch == 'e')
    166. {
    167. int left = PlayerPlane_x - 3;
    168. int right = PlayerPlane_x + 3;
    169. if (skill2 == 5)
    170. {
    171. for (int i = left; i < right; i++)
    172. {
    173. if (i > 0 && i < Row - 1)
    174. {
    175. skill2 = 0;
    176. Bullet_y = PlayerPlane_y - 1;
    177. Bullet_x = i;
    178. arr[Bullet_y][Bullet_x] = 4;
    179. }
    180. }
    181. }
    182. }
    183. }
    184. }
    185. void BulletEnemy(int arr[Col][Row])
    186. {
    187. for (int i = 0; i < Col; i++)
    188. {
    189. for (int j = 0; j < Row; j++)
    190. {
    191. if (arr[i][j] == 4)
    192. {
    193. for (int k = 0; k < Count; k++)
    194. {
    195. //子弹击中敌机的处理
    196. if (i == Enemy_y[k] && j == Enemy_x[k])
    197. {
    198. if (skill1 < 20)
    199. {
    200. skill1++;
    201. }
    202. if (skill2 < 5)
    203. {
    204. skill2++;
    205. }
    206. score += 100;
    207. arr[Enemy_y[k]][Enemy_x[k]] = 0;
    208. Enemy_y[k] = rand() % 3 + 1;
    209. Enemy_x[k] = rand() % Row + 1;
    210. if (Enemy_x[k] >= Row - 1)
    211. Enemy_x[k] -= 2;
    212. arr[Enemy_y[k]][Enemy_x[k]] = 3;
    213. //每2000分敌机加速
    214. if (score % 2000 == 0 && EnemySleep > 4)
    215. {
    216. EnemySleep -= 2;
    217. }
    218. }
    219. }
    220. //子弹的移动
    221. if (arr[i][j] == 4)
    222. {
    223. arr[i][j] = 0;
    224. if (i > 1)
    225. {
    226. arr[i - 1][j] = 4;
    227. }
    228. }
    229. }
    230. }
    231. }
    232. //敌机的移动
    233. if (sleep < EnemySleep)
    234. {
    235. sleep++;
    236. }
    237. else if (sleep > EnemySleep)
    238. {
    239. sleep = 0;
    240. }
    241. for (int i = 0; i < Count; i++)
    242. {
    243. if (PlayerPlane_y == Enemy_y[i] && PlayerPlane_x == Enemy_x[i] || score < 0)
    244. {
    245. printf(" /\\_/\\ \n");//敌机击中玩家飞机的处理
    246. printf(" ( o.o ) \n");
    247. printf(" > ^ < \n");
    248. printf("游戏失败!\n");
    249. printf("\a");
    250. system("pause");
    251. exit(0);
    252. }
    253. //敌机到达最底面的处理
    254. if (Enemy_y[i] >= Col - 2)
    255. {
    256. score -= 100;
    257. arr[Enemy_y[i]][Enemy_x[i]] = 0;
    258. Enemy_y[i] = rand() % 3 + 1;
    259. Enemy_x[i] = rand() % Row + 1;
    260. if (Enemy_x[i] >= Row - 1)
    261. Enemy_x[i] -= 2;
    262. arr[Enemy_y[i]][Enemy_x[i]] = 3;
    263. }
    264. //敌机下移的处理
    265. if (sleep == EnemySleep)
    266. {
    267. for (int j = 0; j < Count; j++)
    268. {
    269. arr[Enemy_y[j]][Enemy_x[j]] = 0;
    270. sleep = 0;
    271. Enemy_y[j]++;
    272. arr[Enemy_y[j]][Enemy_x[j]] = 3;
    273. }
    274. }
    275. }
    276. }
    277. void game()
    278. {
    279. //设置一个存放信息的数组
    280. int arr[Col][Row] = { 0 };
    281. //隐藏光标
    282. HideCursor();
    283. //放置信息
    284. InSet(arr);
    285. //打印游戏界面
    286. DisPlay(arr);
    287. //玩家移动
    288. while (1)
    289. {
    290. //玩家操作
    291. PlayerPlay(arr);
    292. //打印棋盘
    293. DisPlay(arr);
    294. //子弹与敌机的操作
    295. BulletEnemy(arr);
    296. }
    297. }
    298. int main()
    299. {
    300. system("color b");
    301. int input = 0;
    302. menu();
    303. printf("请选择:");
    304. scanf("%d", &input);
    305. switch (input)
    306. {
    307. case 1:
    308. game();
    309. break;
    310. case 0:
    311. printf("退出游戏\n");
    312. break;
    313. default:
    314. printf("输入有误,请重新输入:\n");
    315. break;
    316. }
    317. return 0;
    318. }

    最终效果

    飞机大作战

  • 相关阅读:
    基于rt thread smart构建EtherCAT主站
    【Python】从同步到异步多核:测试桩性能优化,加速应用的开发和验证
    TSN协议解读系列 | (3) Qci:说书唱戏劝人方
    Redis进阶
    MySQL索引,你真的学会了?索引底层原理是什么?索引什么时候失效,你知道吗?
    Java概述
    在 MySQL 中优化分页的 3 种方法
    20 个提升效率的 JS 简写技巧
    Java写一套漂亮的代码,哪些设计模式比较常用?
    LeetCode-698. 划分为k个相等的子集【数组,回溯】
  • 原文地址:https://blog.csdn.net/weixin_58252863/article/details/136354388