方格填数【相邻两数互质】-DFS深度优先搜索

来源:互联网 发布:马家军调查知乎 编辑:程序博客网 时间:2024/05/22 06:49

题目描述:
多组数据,每组九个数字,要求将这九个数字填入一个3 x 3的方格中,使相邻两数互质,即最大公约数为1,求总方案数,处理到文件结尾。

题目链接

示例:
INPUT:
1 1 1 1 1 1 1 1 1
2 2 2 4 4 4 6 6 6
2 2 2 2 2 3 3 3 3

OUTPUT:
362880
0
2880

思路:
第一种思路是先把方格填满,再去判断是否符合条件。这属于暴力破解,不用说,肯定是超时的,该思路直接舍弃。(注:因为很多不可能的方案都进行了一次判断,例如示例2,因为总方案数应该为0,而硬是判断了9!次)

这样就很容易想到第二种思路,边判断边填方格。这样就可以减少不可能方案的判断次数,在中途将其舍弃,开始下一个方案的探索。那用什么实现呢,当然是DFS深度优先搜索啦,下面有百度百科关于DFS的介绍,大家可以看下。

百度百科DFS简介

下面开始上代码:

#include<bits/stdc++.h>using namespace std;/*    *position    *0 1 2    *3 4 5    *6 7 8*/int num[10];            //用来存储输入的数组 int now[10];            //用来储存已经放进数字的数组 bool num_i_exist[10];   //检查数字是否使用过 int ans=0;              //用来存储方案总数 int gcd(int a,int b)    //求最大公约数 {    return a%b==0 ? b : gcd(b,a%b);}bool check(int cur_pos,int num_i) //检查当前位置cur_pos是否可以放置num_i {    if(cur_pos == 0) return true;    if(cur_pos >= 3)    {        if(gcd(now[cur_pos-3],num_i) != 1) return false;        }    if(cur_pos%3 != 0)    {        if(gcd(now[cur_pos-1],num_i) != 1) return false;            //1和i 因为一开始i是全局变量 写错了编译器没有报错 查了半天 智障     }    return true;}void dfs(int cur_pos)       //深度搜索 {    if(cur_pos == 9)                 {        ans++;        return;    }    for(int i=0;i<9;i++)    {        if(num_i_exist[i] == true) continue;        if(check(cur_pos,num[i]) == true)        {            num_i_exist[i] = true;            now[cur_pos] = num[i];            dfs(cur_pos+1);            num_i_exist[i] = false;        }    }}int main(){    while(~scanf("%d",&num[0]))    {        ans=0;        for(int i=1;i<9;i++) scanf("%d",&num[i]);        dfs(0);        printf("%d\n",ans);    }    return 0;}

关于代码的一些注释:
判断文件是否结束:看能不能读取到九个数的第一个数
判断方案是否有效:看第九个数能不能成功填到方格中
某数能否填某位置:后面的数因为还没有填写不予讨论
关于求最大公约数:大数在前在后不影响算法会自动调

最后来一些个人感悟:
因为一开始i设置的是全局变量,把1敲成了i编译器没有提示,而且戴眼镜的我竟然也没有看出来,呜呜呜,反反复复看了无数遍,最后把i设置成局部变量才被编译器发现,我真是太太太太太太太丢脸了!也希望给大家提个醒咯,还有这是我的第一篇博客咯,还请大家多多支持,睡啦,安安。

原创粉丝点击