hdu 2514 Another Eight Puzzle

本文介绍了一种使用深度优先搜索算法解决数字填圈问题的方法,该问题要求将1至8的数字填入给定的圆圈中,使得相连的圆圈所填数字之差不等于1。

  题目的大意就是,给你八个圆圈,将1~8这些数字填入圈中。这些圆圈之中,有些圈是互相连通的,相互连接的圆圈所填入的数字只差不能等于1。

  输入数据中为0的地方是我们需要我们填入数字的。

  从题目要求我们可以知道就是一个搜索题,用dfs直接搜所有的解,第一次搜到解时,保存下来,如果再一次搜到,就说明解不唯一,则直接退出。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
bool mp[10][10];
int ans[10],vis[10];
int num[10],sum;
bool isUnique,flag;
int iabs(int n)
{
    return n>0?n:-n;
}
void createMap()
{
    memset(mp,false,sizeof(mp));
    for(int i=1; i<=8; i++)
        mp[i][i]=true;
    mp[1][2]=mp[2][1]=true;
    mp[1][3]=mp[3][1]=true;
    mp[1][4]=mp[4][1]=true;
    mp[2][3]=mp[3][2]=true;
    mp[2][5]=mp[5][2]=true;
    mp[2][6]=mp[6][2]=true;
    mp[3][4]=mp[4][3]=true;
    mp[3][5]=mp[5][3]=true;
    mp[3][6]=mp[6][3]=true;
    mp[3][7]=mp[7][3]=true;
    mp[4][6]=mp[6][4]=true;
    mp[4][7]=mp[7][4]=true;
    mp[5][6]=mp[6][5]=true;
    mp[6][7]=mp[7][6]=true;
    mp[6][8]=mp[8][6]=true;
    mp[7][8]=mp[8][7]=true;
}
void init()
{
    memset(vis,0,sizeof(vis));
    sum=0;
    isUnique=true;
    flag=false;
    for(int i=1; i<=8; i++)
    {
        scanf("%d",&num[i]);
        if(num[i]!=0)++sum;
        vis[num[i]]=true;
    }
}
bool check(int x,int y)
{
    for(int i=1; i<=8; i++)
    {
        if(!num[i])continue;
        if(mp[x][i] && iabs(num[i]-y)==1)return false;
    }
    return true;
}
bool dfs(int cur,int n)
{
    if(n+sum==8)
    {
        if(flag)
        {
            isUnique=false;
            return true;
        }
        else
        {
            flag=true;
            for(int i=1; i<=8; i++)
                ans[i]=num[i];
            return false;
        }
    }
    for(int i=cur; i<=8; i++)
    {
        if(num[i])continue;
        for(int j=1; j<=8; j++)
        {
            if(vis[j])continue;
            if(!check(i,j))continue;
            vis[j]=true;
            num[i]=j;
            if(dfs(cur+1,n+1))return true;
            vis[j]=false;
            num[i]=0;
        }
        break;
    }
    return false;
}
void solve()
{
    init();
    dfs(1,0);
    if(flag)
    {
        if(isUnique)
        {
            for(int i=1; i<=8; i++)
                printf(" %d",ans[i]);
        }
        else printf(" Not unique");
    }
    else printf(" No answer");
    printf("\n");

}

int main()
{
    int t,cas=0;
  //  freopen("in.txt","r",stdin);
    scanf("%d",&t);
    createMap();
    while(cas++<t)
    {
        printf("Case %d:",cas);
        solve();
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值