HDU-2541-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

题意:按照下图的位置填好之后,相邻位置的数字不能有相邻的

A-H表示位置1--8

难度:判断该数字是否能填,需要每个位置单组判断

/*
按照位置填好之后,相邻的圆圈内不能有相邻的数字
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
using namespace std;
int s[10];//保存输入的数
int a[10];//记录需要填的位置
int save[10];//保存数组
bool v[10];//判断这个数是否
int ans;//判断有几种情况
int cnt;//记录有几个数需要填
bool check(int n,int m);
void dfs(int step);
void print();
int main()
{
    int t,tatal=0;
    scanf("%d",&t);
    while(t--)
    {
        tatal++;//表示第几组数
        ans=0;
        cnt=0;
        memset(s,0,sizeof(s));
        memset(v,0,sizeof(v));
        for(int i=0; i<8; ++i)
        {
            scanf("%d",&s[i]);
            if(s[i])
                v[s[i]]=true;
            else if(s[i]==0)
                 {
                     a[cnt++]=i;
                     s[i]=-1;
                 }
        }
        printf("Case %d: ",tatal);
        dfs(0);
        if(ans==1)//出现一种情况
        {
            for(int i=0; i<7; ++i)
                printf("%d ",save[i]);
            printf("%d\n",save[7]);
        }
        if(ans==0)//判断是否有结果
            printf("No answer\n");
        }
}
void dfs(int step)
{
    if(ans==2)//有多种情况,直接就结束
        return ;
    if(step==cnt&&ans==0)
    {
        ans=1;
        print();//保存结果
        return ;
    }
    else if(step==cnt&&ans==1)//出现第二种情况
    {
        printf("Not unique\n");
        ans=2;
        return ;
    }
    for(int i=1; i<=8; ++i)
    {
        if(check(a[step],i)&&!v[i])
        {
            s[a[step]]=i;//将空的位置填上
            v[i]=true;
            dfs(step+1);
            s[a[step]]=-1;//回溯
            v[i]=false;
        }
    }
}
void print()
{
    for(int i=0; i<8; ++i)//保存
        save[i]=s[i];
}
bool check(int n,int m)//判断填的的是哪个位置
{
    switch(n)
    {
    case 0:
    {
        if(abs(m-s[1])==1||abs(m-s[3])==1||abs(m-s[2])==1)
                return false;
        return true;
    }
        case 1:
        {
            if(abs(m-s[0])==1||abs(m-s[2])==1||abs(m-s[4])==1||abs(m-s[5])==1)
                return false;
        return true;
        }
        case 2:
        {
            if(abs(m-s[0])==1||abs(m-s[1])==1||abs(m-s[3])==1||abs(m-s[4])==1||abs(m-s[5])==1||abs(m-s[6])==1)
                return false;
        return true;
        }
        case 3:
        {
            if(abs(m-s[0])==1||abs(m-s[2])==1||abs(m-s[5])==1||abs(m-s[6])==1)
                return false;
        return true;
        }
        case 4:
        {
            if(abs(m-s[1])==1||abs(m-s[2])==1||abs(m-s[5])==1||abs(m-s[7])==1)
                return false;
        return true;
        }
        case 5:
        {
            if(abs(m-s[2])==1||abs(m-s[1])==1||abs(m-s[4])==1||abs(m-s[7])==1||abs(m-s[6])==1||abs(m-s[3])==1)
                return false;
        return true;
        }
        case 6:
        {
            if(abs(m-s[3])==1||abs(m-s[2])==1||abs(m-s[5])==1||abs(m-s[7])==1)
                return false;
        return true;
        }
        case 7:
        {
            if(abs(m-s[4])==1||abs(m-s[5])==1||abs(m-s[6])==1)
                return false;
        return true;
        }
    }
}








 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值