HDU 2514 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.
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

题解:类似数独问题,将8个数字填入图中,连线两端的数字不能连续,因为线有17条,所以check函数写得非常长,其他的跟一般的DFS题目没有大区别,就是其他的题目只需恢复标记数组,而这个题目还需要恢复填写数字的数组。

#include <cstdio>
#include <iostream>
#include <string>
#include <sstream>
#include <cstring>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <map>
#define PI acos(-1.0)
#define ms(a) memset(a,0,sizeof(a))
#define msp memset(mp,0,sizeof(mp))
#define msv memset(vis,0,sizeof(vis))
using namespace std;
//#define LOCAL
int sign[10];
int mp[10];
int ans,res[10];
bool check(int n)
{
    switch(n)
    {
    case 1:
    {
        if(abs(mp[0]-mp[1])==1)return 0;
        return 1;
    }
    case 2:
    {
        if(abs(mp[0]-mp[2])==1)return 0;
        if(abs(mp[1]-mp[2])==1)return 0;
        return 1;
    }
    case 3:
    {
        if(abs(mp[0]-mp[3])==1)return 0;
        if(abs(mp[2]-mp[3])==1)return 0;
        return 1;
    }
    case 4:
    {
        if(abs(mp[2]-mp[4])==1)return 0;
        if(abs(mp[1]-mp[4])==1)return 0;
        return 1;
    }
    case 5:
    {
        if(abs(mp[1]-mp[5])==1)return 0;
        if(abs(mp[2]-mp[5])==1)return 0;
        if(abs(mp[3]-mp[5])==1)return 0;
        if(abs(mp[4]-mp[5])==1)return 0;
        return 1;
    }
    case 6:
    {
        if(abs(mp[2]-mp[6])==1)return 0;
        if(abs(mp[3]-mp[6])==1)return 0;
        if(abs(mp[5]-mp[6])==1)return 0;
        return 1;
    }
    case 7:
    {
        if(abs(mp[4]-mp[7])==1)return 0;
        if(abs(mp[5]-mp[7])==1)return 0;
        if(abs(mp[6]-mp[7])==1)return 0;
        return 1;
    }
    }
    return 1;
}
void dfs(int n)
{
    if(n==7)
    {
        if(mp[n]==0)
        {
            for(int i=1; i<=8; i++)
            {
                if(sign[i]==0)
                {
                    mp[n]=i;
                    sign[i]=1;
                    if(check(n))
                    {
                        ans++;
                        for(int j=0; j<8; j++)
                            res[j]=mp[j];
                    }
                    sign[i]=0;
                    mp[n]=0;
                }
            }
        }
        else
        {
            if(check(n))
            {
                ans++;
                for(int j=0; j<8; j++)
                    res[j]=mp[j];
            }
        }
    }
    else
    {
        if(mp[n]==0)
        {
            for(int i=1; i<=8; i++)
            {
                if(sign[i]==0)
                {
                    mp[n]=i;
                    sign[i]=1;
                    if(check(n))dfs(n+1);
                    sign[i]=0;
                    mp[n]=0;
                }
            }
        }
        else
        {
            if(check(n))dfs(n+1);
        }
    }
    return;
}
int main()
{
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
#endif // LOCAL
    ios::sync_with_stdio(false);
    int n,cas=0;
    cin>>n;
    while(n--)
    {
        cas++;
        ans=0,ms(res),ms(mp),ms(sign);
        for(int i=0; i<8; i++)
        {
            cin>>mp[i];
            if(mp[i]!=0)sign[mp[i]]=1;
        }
        for(int i=0; i<8; i++)
        {
            if(mp[i]==0)
            {
                dfs(i);
                break;
            }
        }
        if(ans==1)
        {
            printf("Case %d:",cas);
            for(int i=0; i<8; i++)
                printf(" %d",res[i]);
            printf("\n");
        }
        else if(ans==0)printf("Case %d: No answer\n",cas);
        else printf("Case %d: Not unique\n",cas);
    }
    return 0;
}
时间: 2024-08-06 03:45:05

HDU 2514 Another Eight Puzzle(DFS)的相关文章

HDU 1098 Ignatius&#39;s puzzle 费马小定理+扩展欧几里德算法

题目大意: 给定k,找到一个满足的a使任意的x都满足 f(x)=5*x^13+13*x^5+k*a*x 被65整除 推证: f(x) = (5*x^12 + 13 * x^4 + ak) * x 因为x可以任意取 那么不能总是满足 65|x 那么必须是 65 | (5*x^12 + 13 * x^4 + ak) 那么就是说 x^12 / 13 + x^4 / 5 + ak / 65 正好是一个整数 假设能找到满足的a , 那么将 ak / 65 分进x^12 / 13 + x^4 / 5中得到

HDU 哈密顿绕行世界问题 (dfs)

Problem Description 一个规则的实心十二面体,它的 20个顶点标出世界著名的20个城市,你从一个城市出发经过每个城市刚好一次后回到出发的城市. Input 前20行的第i行有3个数,表示与第i个城市相邻的3个城市.第20行以后每行有1个数m,m<=20,m>=1.m=0退出. Output 输出从第m个城市出发经过每个城市1次又回到m的所有路线,如有多条路线,按字典序输出,每行1条路线.每行首先输出是第几条路线.然后个一个: 后列出经过的城市.参看Sample output

HDU 1241 Oil Deposits --- 入门DFS

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1241 /* HDU 1241 Oil Deposits --- 入门DFS */ #include <cstdio> int m, n; //n行m列 char mapp[105][105]; /* 将和i,j同处于一个连通块的字符标记出来 */ void dfs(int i, int j){ if (i < 0 || j < 0 || i >= n || j >= m

hdu 2489 Minimal Ratio Tree(dfs枚举 + 最小生成树)~~~

题目: 链接:点击打开链接 题意: 输入n个点,要求选m个点满足连接m个点的m-1条边权值和sum与点的权值和ans使得sum/ans最小,并输出所选的m个点,如果有多种情况就选第一个点最小的,如果第一个点也相同就选第二个点最小的........ 思路: 求一个图中的一颗子树,使得Sum(edge weight)/Sum(point weight)最小~ 数据量小,暴力枚举~~~~~dfs暴力枚举C(M,N)种情况. 枚举出这M个点之后,Sum(point weight)固定,进行prim或者K

HDU 1098 Ignatius&#39;s puzzle 也不大懂

http://acm.hdu.edu.cn/showproblem.php?pid=1098 看了一下它们的思路,没完全明白,但是能写出来,大概可能也许就是这样做的吧. 1 #include <iostream> 2 using namespace std; 3 typedef long long ll; 4 5 int main() { 6 ll k; 7 while (cin>>k) 8 { 9 int flag = 0,a; 10 for ( a = 1; a <= 6

[2016-02-05][HDU][1097][A hard puzzle]

[2016-02-05][HDU][1097][A hard puzzle] HDU - 1097 A hard puzzle Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u Submit Status Description lcy gives a hard puzzle to feng5166,lwg,JGShining and Ignatius: gave a and b,how to know

HDU - 1098 - Ignatius&#39;s puzzle (数论 - 费马小定理)

Ignatius's puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7012    Accepted Submission(s): 4847 Problem Description Ignatius is poor at math,he falls across a puzzle problem,so he has no

HDU 1010 Tempter of Bone DFS + 奇偶剪枝

奇偶剪枝: 对于从起始点 s 到达 终点 e,走且只走 t 步的可达性问题的一种剪枝策略. 如下列矩阵 : 从任意 0 到达 任意 0,所需步数均为偶数,到达任意 1 ,均为奇数.反之亦然 所以有,若s走且只走 t 步可到达e,则必有t >= abs(s.x - e.x) + abs(s.y - e.y),且 (t&1) == ((abs(s.x - e.x) + abs(s.y - e.y))&1). 否则必不可达. #include <iostream> #inclu

杭电 HDU 1098 Ignatius&#39;s puzzle

Ignatius's puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7068    Accepted Submission(s): 4883 Problem Description Ignatius is poor at math,he falls across a puzzle problem,so he has no