2016年第七届蓝桥杯C/C++A组第三题---方格填数
2017-10-13 20:45
281 查看
在练习算法的时候,看见了这个题,利用递归回溯的方法,解开了这个题
问题描述:
方格填数
如下的10个格子
填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
以上就是问题的描述,第一感觉是枚举,但是想想,枚举可能超时,而且不好写,进而转变为其他的思路。
我们可以将这个问题分解为规模更小的子问题。例如已经填好了k个格子,在k个格子的基础上,我们进行处理问题,这样很容易就想到了递归的方法。
我们首先将格子规范化为下图这样
这样做的好处是,在判断当前数字和周围数字是否相邻的时候,可以采取统一的操作,即遍历以其自己为中心的9个方格,当然在遍历到其自身的时候跳过。
多增加的格子里的数字和所填的数字始终不会相邻,这样就不会对结果造成影响,而且可以规范判断时的操作。
以下是完整代码,代码后有注释
问题描述:
方格填数
如下的10个格子
填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
以上就是问题的描述,第一感觉是枚举,但是想想,枚举可能超时,而且不好写,进而转变为其他的思路。
我们可以将这个问题分解为规模更小的子问题。例如已经填好了k个格子,在k个格子的基础上,我们进行处理问题,这样很容易就想到了递归的方法。
我们首先将格子规范化为下图这样
这样做的好处是,在判断当前数字和周围数字是否相邻的时候,可以采取统一的操作,即遍历以其自己为中心的9个方格,当然在遍历到其自身的时候跳过。
多增加的格子里的数字和所填的数字始终不会相邻,这样就不会对结果造成影响,而且可以规范判断时的操作。
以下是完整代码,代码后有注释
#include <iostream> #include <math.h> using namespace std; int a[5][6];//开辟数组,为了保持统一性,在原来的方格的上下左右都新添了一行 bool num[10];//存放0-9这个10个数字的使用情况 int p=0;//记录方法数 bool flag = true;//标记当前的填法是否成功 void judge(int i,int j) { if (i == 3 && j == 4)//当填到第a[3][4]的时候,成功,因为图中的格子只到a[3][3] { p++; return; } for (int k=0;k<=9;k++)//遍历10个数字 { flag = true; if (num[k]==false)//当前的数字没有被使用 { a[i][j] = k;//令当前的这个格子的数字为k num[k]=tr 4000 ue;//令这个数字为已使用状态 } else continue;//如果当前的数字已经使用了,那么跳过 for (int m = -1; m <= 1; m++)//如果当前的数字可以使用,那么检验自己周围的格子,看看是否满足条件,算上自己应该有9个格子,以自己为中心 { for (int n = -1; n <= 1; n++) { if (m == 0 && n == 0)//如果要检查的格子为自身,直接跳过 continue; if (abs(a[i][j] - a[i + m][j + n]) == 1)//绝对值相差为1,意味着为连续数字 { num[k] = false;//当前使用的数字被还回去 flag = false;//当前方法不成功 } } } if (flag == false)//如果当前方法不成功,那么继续尝试下一个数字 continue; else//如果成功则继续下一个数字 { if (j == 4) { judge(i + 1, 1);//当到达最右边的时候,重新进入下一行的考察 num[k] = false;//返回的时候,把占用的数字还回去,因为当返回的时候,意味以当前这个k延伸出去的所有解法已经没有 //所以要将当前的这个格子的数字调整为k+1,所以刚刚使用的k应该被还回去,所以设置k的状态为false未使用 } else { judge(i, j + 1);//没有到达最右的时候,向右 num[k] = false;//返回的时候,把占用的数字还回去,道理同上 } } } a[i][j] = -10;//当前这个格子的问题结束了,把格子置为未使用状态 } int main() { int i, j; for (i=0;i<10;i++)//初始化数字状态数组 num[i] = false; for (i=0;i<5;i++)//初始化格子,都是未使用状态,-10也可以是别的数字,只要别和0-9连续 for (j=0;j<6;j++) a[i][j] = -10; judge(1, 2);//从a[1][2]开始填 cout << p<<endl;//输出方法总数 cin >> p; return 0; }
相关文章推荐
- 蓝桥杯_2016年第七届C/C++B组—6.方格填数 【DFS】
- 【DFS填数】(2016)第七届蓝桥杯省赛 C/C++ A组 题解(第三题)
- 2016年第七届蓝桥杯Java 方格填数
- 2016年第七届蓝桥杯c/c++省赛B组
- 2016第七届蓝桥杯C++B组第六题:方格填数
- 蓝桥杯2016年第七届省赛C_C++程序设计本科B组
- 第七届蓝桥杯C++B组 方格填数
- 2016年第七届蓝桥杯省赛(C/C++ A组)
- 煤球数目(2016年第七届蓝桥杯c/c++省赛B组(1题))
- 第七届蓝桥杯大赛个人赛省赛(软件类)A组第三题 方格填数
- 方格填数-第七届蓝桥杯c/c++B组
- 2016第七届蓝桥杯C/C++ B组省赛第三题:凑算式
- 第七届 蓝桥杯 c/c++ B组 省赛 (6)——方格填数
- 2016年第七届蓝桥杯c/c++省赛B组
- 第七届蓝桥杯C\C++B组省赛题目——方格填数
- 16年第七届蓝桥杯第三题_方格填数
- 2016年第七届蓝桥杯省赛(C/C++ A组)
- 2016年蓝桥杯A组第三题 方格填数
- 2016年第七届蓝桥杯试题(C/C++本科B组)1-8题
- 2016年第七届蓝桥杯C/C++B组第十题