题目的大意就是,给你八个圆圈,将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;
}