HDU [ Another Eight Puzzle ]——dfs全排列变式

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.<br>There are 17 pairs of connected cicles:<br>A-B , A-C, A-D<br>B-C, B-E, B-F<br>C-D, C-E, C-F, C-G<br>D-F, D-G<br>E-F, E-H<br>F-G, F-H<br>G-H<br><center><img src=../../../data/images/C150-1010-1.jpg></center><br>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 .<br><br>In this problems,some circles are already filled,your tast is to fill the remaining circles to obtain a solution (if possivle).<br>
 

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.<br><br>
 

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”.<br>
 

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,一个按照题目规则标记目标位置不能存放哪些数,另一个用于回溯时重置状态(因为会有多个位置指向同一位置,所以将标记数组写为int型)。

        最后,也是最关键的地方,就是把放数的规则看懂,因为这个,自己调了一下午,下面从网上搜了一张。


        

        

        明白了规则,再写就很简单了。

  AC代码:(自己写的复杂点)


#include<iostream>
#include<cstring>
using namespace std;
int a[10];//输入;
int position[10];//所有为0的位置;
int memor[10];//存储输出;
bool flag_num[10];
int flag_pos[10][10];//num该数字是否用过,pos该位置是否能用该数;
int k=0,sum=0;//sum所有数的和;k为零数的个数;
int ans;//方案数;
int flag_ans;//用于判断输出内容;
void flag_fun(int x,int y)
{
    if(x==1)
    {
        flag_pos[2][y]++;flag_pos[2][y-2]++;
        flag_pos[3][y]++;flag_pos[3][y-2]++;
        flag_pos[4][y]++;flag_pos[4][y-2]++;
    }
    else if(x==2)
    {
        flag_pos[3][y]++;flag_pos[3][y-2]++;
        flag_pos[5][y]++;flag_pos[5][y-2]++;
        flag_pos[6][y]++;flag_pos[6][y-2]++;
    }
    else if(x==3)
    {
        flag_pos[4][y]++;flag_pos[4][y-2]++;
        flag_pos[5][y]++;flag_pos[5][y-2]++;
        flag_pos[6][y]++;flag_pos[6][y-2]++;
        flag_pos[7][y]++;flag_pos[7][y-2]++;
    }
    else if(x==4)
    {
        flag_pos[6][y]++;flag_pos[6][y-2]++;
        flag_pos[7][y]++;flag_pos[7][y-2]++;
    }
    else if(x==5)
    {
        flag_pos[6][y]++;flag_pos[6][y-2]++;
        flag_pos[8][y]++;flag_pos[8][y-2]++;
    }
    else if(x==6)
    {
        flag_pos[7][y]++;flag_pos[7][y-2]++;
        flag_pos[8][y]++;flag_pos[8][y-2]++;
    }
    else if(x==7)
    {
        flag_pos[8][y]++;
        flag_pos[8][y-2]++;
    }
}
void f_flag_fun(int x,int y)
{
    if(x==1)
    {
        flag_pos[2][y]--;flag_pos[2][y-2]--;
        flag_pos[3][y]--;flag_pos[3][y-2]--;
        flag_pos[4][y]--;flag_pos[4][y-2]--;
    }
    else if(x==2)
    {
        flag_pos[3][y]--;flag_pos[3][y-2]--;
        flag_pos[5][y]--;flag_pos[5][y-2]--;
        flag_pos[6][y]--;flag_pos[6][y-2]--;
    }
    else if(x==3)
    {
        flag_pos[4][y]--;flag_pos[4][y-2]--;
        flag_pos[5][y]--;flag_pos[5][y-2]--;
        flag_pos[6][y]--;flag_pos[6][y-2]--;
        flag_pos[7][y]--;flag_pos[7][y-2]--;
    }
    else if(x==4)
    {
        flag_pos[6][y]--;flag_pos[6][y-2]--;
        flag_pos[7][y]--;flag_pos[7][y-2]--;
    }
    else if(x==5)
    {
        flag_pos[6][y]--;flag_pos[6][y-2]--;
        flag_pos[8][y]--;flag_pos[8][y-2]--;
    }
    else if(x==6)
    {
        flag_pos[7][y]--;flag_pos[7][y-2]--;
        flag_pos[8][y]--;flag_pos[8][y-2]--;
    }
    else if(x==7)
    {
        flag_pos[8][y]--;
        flag_pos[8][y-2]--;
    }
}
void search(int x)
{
   if(x>k)
   {
      //cout<<sum<<" "<<a[7]<<" "<<a[8]<<endl;
      ans++;
      if(ans==1)
          for(int i=1;i<=8;++i)memor[i]=a[i],flag_ans=1;
      else if(ans>1)
      {
          flag_ans=2;
      }
      else flag_ans=0;
      return ;
   }
   for(int i=1;i<=8;++i)
   {
       if(flag_num[i]==0&&flag_pos[position[x]][i]==0)
       {
           sum+=i;
           flag_num[i]=1;
           flag_fun(position[x],i+1);
           a[position[x]]=i;
           search(x+1);
           a[position[x]]=0;
           f_flag_fun(position[x],i+1);
           flag_num[i]=0;
           sum-=i;
       }
   }

}
int main()
{
    int t,temp=0;
    cin>>t;
    while(t--)
    {
        temp++;
        memset(a,0,sizeof(a));
        memset(flag_num,0,sizeof(flag_num));
        memset(flag_pos,0,sizeof(flag_pos));
        memset(position,0,sizeof(position));
        memset(memor,0,sizeof(memor));
        k=0;sum=0;ans=0;flag_ans=0;
        for(int i=1;i<=8;++i)
        {
            cin>>a[i];
            if(a[i]!=0)
            {
                sum+=a[i];
                flag_num[a[i]]=1;
                flag_fun(i,a[i]+1);//函数:该位置数字确定后,哪些位置不能再放哪些数;
            }
            else
            {
                position[++k]=i;
            }
        }
        search(1);
        cout<<"Case "<<temp<<":";
        if(flag_ans==1)
        {
            for(int i=1;i<=8;++i)cout<<" "<<memor[i];
            cout<<endl;
        }
        else if(flag_ans==2)cout<<" Not unique"<<endl;
        else if(flag_ans==0)cout<<" No answer"<<endl;
    }
    return 0;
}

The end;



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值