ACM-DFS之Another Eight Puzzle——hdu2514

来源:互联网 发布:查肝功能多少钱 知乎 编辑:程序博客网 时间:2024/05/24 05:24
Another Eight Puzzle

题目:http://acm.hdu.edu.cn/showproblem.php?pid=2514

Problem Description

Fill the following 8 circles with digits 1~8,with each number exactly once . Conntcted circles cannot be filled with two consecutive numbers.
There are 17 pairs of connected cicles:
A-B , A-C, A-D
B-C, B-E, B-F
C-D, C-E, C-F, C-G
D-F, D-G
E-F, E-H
F-G, F-H
G-H


Filling G with 1 and D with 2 (or G with 2 and D with 1) is illegal since G and D are connected and 1 and 2 are consecutive .However ,filling A with 8 and B with 1 is legal since 8 and 1 are not consecutive .

In this problems,some circles are already filled,your tast is to fill the remaining circles to obtain a solution (if possivle).

Input
The first line contains a single integer T(1≤T≤10),the number of test cases. Each test case is a single line containing 8 integers 0~8,the numbers in circle A~H.0 indicates an empty circle.

Output
For each test case ,print the case number and the solution in the same format as the input . if there is no solution ,print “No answer”.If there more than one solution,print “Not unique”.

Sample Input
3
7 3 1 4 5 8 0 0
7 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0

Sample Output
Case 1: 7 3 1 4 5 8 6 2
Case 2: Not unique

Case 3: No answer


很有意思的一道DFS,感觉有点类似于数独了。。

看图更明白一些,就是向图中每个圈圈都放一个数字(1~8)

使得每个线段相邻的圈圈的数字不能是连续的

比如A和B、C、D是相连的,那么如果A是2,B,C,D中任何一个都不能是1或者3


解题的关键在于判断是否是连续的数字,

我的处理启发与题目中的相连,每次都从A开始找,找到最后,这样因为A和B搜索过,B就不需要再搜索A,

怎么实现?用一个for加switch就可以搞定啦,(*^__^*) 嘻嘻……

我的dfs函数传递参数只有一个就是n,代表要填第几个数,如果当前数不为0,dfs(n+1),如果为0,从vis搜索,

看哪一个没用过,就用哪一个,恢复现场的时候,不仅要恢复vis数组,还需要恢复原来数组为0,不回复0,下一次搜索发现当前不为0直接进行下一个,肯定就WA啦。。

恩,就是这样。。我switch写的有点麻烦的感觉,但是条例上应该蛮清晰的,不知道是否有更简练的。。


#include <iostream>#include <string.h>using namespace std;int a[9],b[9];bool isun,isan,vis[9];// 自己做一个 求绝对值的函数= =。int abs(int a){    return a<0?-a:a;}bool je(int x,int y){    // 如果两者任意一个是0  要按正确处理,让下一次判断来筛掉    if(!a[x] || !a[y])  return false;    if(abs(a[x]-a[y])==1)  return true;    return false;}// 判断每个位置是否满足题意bool judge(int wz){    bool is;    int i;    for(i=1;i<=wz;++i)    {        switch(i)        {        case 1:            {                if(!je(1,2) && !je(1,3) && !je(1,4))  is=1;                else    is=0;            };break;        case 2:            {                if(!je(2,3) && !je(2,5) && !je(2,6))  is=1;                else    is=0;            };break;        case 3:            {                if(!je(3,4) && !je(3,5) && !je(3,6) && !je(3,7))  is=1;                else    is=0;            };break;        case 4:            {                if(!je(4,6) && !je(4,7))  is=1;                else    is=0;            };break;        case 5:            {                if(!je(5,6) && !je(5,8))  is=1;                else    is=0;            };break;        case 6:            {                if(!je(6,7) && !je(6,8))  is=1;                else    is=0;            };break;        case 7:            {                if(!je(7,8))  is=1;                else    is=0;            };break;        default:break;        }        if(!is) return false;    }    if(!is)  return false;    return true;}void dfs(int n){    int i;    if(isun)    return;    if(n==9 && isan==1){isun=1;return;}    if(n==9)    {        // 将正确的数存起来        for(int j=1;j<=8;++j)            b[j]=a[j];        isan=1;        return;    }    if(a[n]!=0) dfs(n+1);    else    {        for(i=1;i<=8;++i)        {            if(vis[i]==0 && judge(n))            {                vis[i]=1;                a[n]=i;                dfs(n+1);                // 不止vis数组恢复为0,a[n]也要恢复                a[n]=0;                vis[i]=0;            }        }    }}int main(){    int total,i;    cin>>total;    for(int num=1;num<=total;++num)    {        memset(vis,0,sizeof(vis));        for(i=1;i<=8;++i)        {            cin>>a[i];            if(a[i]!=0) vis[a[i]]=1;        }        // isun表示是否有多个答案   isan表示是否有答案        isun=0;        isan=0;        dfs(1);        cout<<"Case "<<num<<":";        if(isan==0 && isun==0)    cout<<" No answer"<<endl;        else if(isun==1 && isan==1)  cout<<" Not unique"<<endl;        else if(isun==0 && isan==1)        {            for(i=1;i<=8;++i)                cout<<" "<<b[i];            cout<<endl;        }    }    return 0;}


0 0
原创粉丝点击