hdu(2514) Another Eight Puzzle

/*先把题意给搞懂了就好办了;
题意;给出把个各位的点,并给出了所有有关联位置的点,
      这些有关连的的位置上的数都不能是连续的;
   已经给出八个点以及各点的连接情况,要求两个相连的点
   的值不能连续,输入部分点的值,让你填其他点的值,
   检查能否填出已经是否有唯一解。

只有八个点,把要填的数值排序填入点中,然后检查一下就可以了。*/


//思路;
//首先把有关连的点用visit表示出来,注意双向性;然后在输入的时候把那些不是零的点表记起来,
//再用bfs从一开始搜到九结束,对于那些是零的位置,用ok函数找出与此位置都是关联的位置,只要这些位置的值
//都都不是连续的就可以把为零的位置赋予此值。。
//最后用回朔搜索;


#include"stdio.h"
#include"string.h"
#include"math.h"
int visit[10][10];
int mark[10],map[10];
int a[10],m;
void fun()
{
 memset(visit,0,sizeof(visit));
 visit[1][2]=visit[1][3]=visit[1][4]=1;
    visit[2][1]=visit[3][1]=visit[4][1]=1;
    visit[2][3]=visit[2][5]=visit[2][6]=1;
    visit[3][2]=visit[5][2]=visit[6][2]=1;
    visit[3][4]=visit[3][5]=visit[3][6]=visit[3][7]=1;
    visit[4][3]=visit[5][3]=visit[6][3]=visit[7][3]=1;
    visit[4][6]=visit[4][7]=1;
    visit[6][4]=visit[7][4]=1;
    visit[5][6]=visit[5][8]=1;
    visit[6][5]=visit[8][5]=1;
    visit[6][7]=visit[6][8]=1;
    visit[7][6]=visit[8][6]=1;
    visit[7][8]=visit[8][7]=1;
}
int ok(int p,int t)
{
 for(int i=1;i<=8;i++)
 {
  if(visit[p][i]&&map[i])
  {
   if(abs(map[i]-t)<2)
    return 0;
  }
 }
 return 1;
}
void bfs(int n)
{
 int i;
 if(n==9)//这里不是8的原因是需要把a【8】也得找出来。
 {
  for(i=1;i<=8;i++)
   a[i]=map[i];
  m++;
  return ;
 }
 if(map[n])
  bfs(n+1);
 else
 {
  for(i=1;i<=8;i++)
  {
   if(mark[i]==0&&ok(n,i))
   {
    mark[i]=1;
    map[n]=i;
    bfs(n+1);
    map[n]=0;
    mark[i]=0;
   }
  }
 }
}
int main()
{
 int i,k,r=1;
 scanf("%d",&k);
 while(k--)
 {
  memset(mark,0,sizeof(mark));
  for(i=1;i<=8;i++)
  {
   scanf("%d",&map[i]);
   if(map[i])
    mark[map[i]]=1;
  }
  m=0;
  fun();
  bfs(1);
  printf("Case %d: ",r++);
  if(m==0)
   printf("No answer\n");
  else if(m>1)
   printf("Not unique\n");
  else
  {
   for(i=1;i<=7;i++)
    printf("%d ",a[i]);
   printf("%d\n",a[8]);
  }
 }
 return 0;
}

 

 

 

 

 

 

 

#include<stdio.h> 
#include<math.h>  
#include<string.h> 
int a[10],vis[10],ans[10],anscnt; 
int ok() 

     if(abs(a[2]-a[1])!=1&& 
        abs(a[3]-a[1])!=1&& 
        abs(a[4]-a[1])!=1&& 

        abs(a[2]-a[3])!=1&& 
        abs(a[2]-a[5])!=1&& 
        abs(a[2]-a[6])!=1&& 
           

         abs(a[3]-a[4])!=1&& 
         abs(a[3]-a[5])!=1&& 
         abs(a[3]-a[6])!=1&& 
         abs(a[3]-a[7])!=1&&           

         abs(a[4]-a[6])!=1&& 
         abs(a[4]-a[7])!=1&&             

         abs(a[5]-a[6])!=1&& 
         abs(a[5]-a[8])!=1&& 

         abs(a[6]-a[7])!=1&& 
         abs(a[6]-a[8])!=1&&      
         abs(a[7]-a[8])!=1) 
        return 1; 
     else
   return 0; 
 } 
void DFS(int k) 
 { 
     int i,cnt=0; 
     if(k==9) //注意这里是k==9 而不是把让它等于8之后放在调用函数的最后面 那样的话 最后一次的赋值就会被还原为0 
       { 
           if(ok()) 
           { 
                 anscnt++; 
                if(anscnt==1) 
                 { 
                    for(i=1;i<=8;i++) 
                        ans[i]=a[i]; 
                } 
             } 
            return; 
         } 
     if(anscnt>=2)
   return; 
     if(a[k])
   DFS(k+1); 
     else
        for(i=1;i<=8;i++) 
         { 
             if(!vis[i]) 
            { 
                 a[k]=i; 
                 vis[i]=1; 
                DFS(k+1); 
                a[k]=0; 
                vis[i]=0; 
            } 
        } 
 } 
 int main() 
 { 
     int t,cas=0; 
     scanf("%d",&t); 
     while(t--) 
     { 
         anscnt=0; 
       int i; 
         memset(vis,0,sizeof(vis)); 
         memset(ans,0,sizeof(ans)); 
         scanf("%d %d %d %d %d %d %d %d",&a[1],&a[2],&a[3],&a[4],&a[5],&a[6],&a[7],&a[8]); 
         for(i=1;i<=8;i++)
    vis[a[i]]=1; 
         DFS(1); 
         printf("Case %d: ",++cas); 
         if(anscnt==1) 
         { 
             for(i=1;i<8;i++)
   printf("%d ",ans[i]); 
             printf("%d\n",ans[i]); 
         } 
         else if(anscnt==0)
    printf("No answer\n"); 
         else
    printf("Not unique\n"); 
    } 
     return 0; 

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值