Another Eight Puzzle
2016-04-11 09:50
465 查看
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
Eight Puzzle" title="Another Eight Puzzle">
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 题意:如图所示,有A-H 8个圆圈,关系如图所示,给出各个圆圈内的数,0代表你要填的数,让你求要多少种填法; 解题思路:刚看到时,以为和相邻两个数的和是素数那个差不多,后来写的时候,有点不一样那个,从第一位开始搜索,位上有数字就跳过,如果没有就搜索: A-B , A-C, A-D
B-A, B-C, B-E, B-F
C-A, C-B, C-D, C-F, C-E,C-G
D-A, D-C, D-F, D-G
E-B, E-C, E-F, E-H
F-C, F-D, F-G, F-H, F-E, F-B
G-D, G-C, G-F, G-H
H-E, H-F, H-G
A=1 B=2 C=3 D=4 E=5 F=6 G=7 H=8 每到一位的判断关系; 感悟:判断条件老是写不对,真是费劲啊 代码: #include
#include
#include
#include
#include
#define maxn 10
using namespace std;
int pos[maxn],t,visit[maxn],ans=0,mark[maxn],p[maxn];
bool conect(int x,int y)
{
if (x>y) {int t=x; x=y; y=t;}
switch (x)
{
case 1:return y==2 || y==3 || y==4;
case 2:return y==3 || y==5 || y==6;
case 3:return y==4 || y==5 || y==6 || y==7;
case 4:return y==6 || y==7;
case 5:return y==6 || y==8;
case 6:return y==7 || y==8;
case 7:return y==8;
}
}
bool ok(int p)
{
int i;
for (i=1;i<=8;i++)
if ((conect(i,p) && abs(pos[p]-pos[i])==1) && pos[i]!=0) return 0;
return 1;
}
void dfs(int cur)
{
//cout<<cur<<" ";
if(ans>1)
return ;//剪枝大于2了就不需要在搜了
//cout<<"cur="<<cur<<endl;
while(cur<=8&&pos[cur]) cur++;//把0空过去
if(cur>8)
{
ans++;
if(ans==1)//因为只有ans=1时才需要输出
memcpy(p,pos,sizeof(pos));//将整个数组转移过来
return;
}
for(int i=1;i<=8;i++) if(!visit[i])
{
//cout<<cur<<endl;
//cout<<i<<" ";
visit[i]=1;
pos[cur]=i;
if(ok(cur))//相邻的不是相邻的数
dfs(cur+1);
pos[cur]=0;//原来这里就是零的
visit[i]=0;//释放标记,用于下一次搜索;
if(ans>1)
return;
}
}
int main()
{
//freopen("in.txt", "r", stdin);
int flag=0;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
ans=0;
memset(pos,0,sizeof(pos));
memset(visit,0,sizeof(visit));
for(int j=1;j<=8;j++)
{
scanf("%d",&pos[j]);
visit[pos[j]]=1;
}
dfs(1);
//cout<<"ans="<<ans<<endl;
printf("Case %d: ",i);
if(!ans)
printf("No answer");
else if(ans==1)
for(int i=1;i<=8;i++)
printf(i==1?"%d":" %d",p[i]);
else
printf("Not unique");
printf("\n");
}
}
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 题意:如图所示,有A-H 8个圆圈,关系如图所示,给出各个圆圈内的数,0代表你要填的数,让你求要多少种填法; 解题思路:刚看到时,以为和相邻两个数的和是素数那个差不多,后来写的时候,有点不一样那个,从第一位开始搜索,位上有数字就跳过,如果没有就搜索: A-B , A-C, A-D
B-A, B-C, B-E, B-F
C-A, C-B, C-D, C-F, C-E,C-G
D-A, D-C, D-F, D-G
E-B, E-C, E-F, E-H
F-C, F-D, F-G, F-H, F-E, F-B
G-D, G-C, G-F, G-H
H-E, H-F, H-G
A=1 B=2 C=3 D=4 E=5 F=6 G=7 H=8 每到一位的判断关系; 感悟:判断条件老是写不对,真是费劲啊 代码: #include
#include
#include
#include
#include
#define maxn 10
using namespace std;
int pos[maxn],t,visit[maxn],ans=0,mark[maxn],p[maxn];
bool conect(int x,int y)
{
if (x>y) {int t=x; x=y; y=t;}
switch (x)
{
case 1:return y==2 || y==3 || y==4;
case 2:return y==3 || y==5 || y==6;
case 3:return y==4 || y==5 || y==6 || y==7;
case 4:return y==6 || y==7;
case 5:return y==6 || y==8;
case 6:return y==7 || y==8;
case 7:return y==8;
}
}
bool ok(int p)
{
int i;
for (i=1;i<=8;i++)
if ((conect(i,p) && abs(pos[p]-pos[i])==1) && pos[i]!=0) return 0;
return 1;
}
void dfs(int cur)
{
//cout<<cur<<" ";
if(ans>1)
return ;//剪枝大于2了就不需要在搜了
//cout<<"cur="<<cur<<endl;
while(cur<=8&&pos[cur]) cur++;//把0空过去
if(cur>8)
{
ans++;
if(ans==1)//因为只有ans=1时才需要输出
memcpy(p,pos,sizeof(pos));//将整个数组转移过来
return;
}
for(int i=1;i<=8;i++) if(!visit[i])
{
//cout<<cur<<endl;
//cout<<i<<" ";
visit[i]=1;
pos[cur]=i;
if(ok(cur))//相邻的不是相邻的数
dfs(cur+1);
pos[cur]=0;//原来这里就是零的
visit[i]=0;//释放标记,用于下一次搜索;
if(ans>1)
return;
}
}
int main()
{
//freopen("in.txt", "r", stdin);
int flag=0;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
ans=0;
memset(pos,0,sizeof(pos));
memset(visit,0,sizeof(visit));
for(int j=1;j<=8;j++)
{
scanf("%d",&pos[j]);
visit[pos[j]]=1;
}
dfs(1);
//cout<<"ans="<<ans<<endl;
printf("Case %d: ",i);
if(!ans)
printf("No answer");
else if(ans==1)
for(int i=1;i<=8;i++)
printf(i==1?"%d":" %d",p[i]);
else
printf("Not unique");
printf("\n");
}
}
相关文章推荐
- leetcode02-Add Two Numbers之beats98.68%Java版本
- css3学习笔记(一):伸缩布局盒模型flexbox
- 使用logrotate管理nginx日志文件
- ZOJ 3935 2016
- php Curl_setop 的学习
- Redis详解与常见问题解决方案
- linux anaconda 和 jupyter配置
- win7系统如何配置adb环境变量 图文详解win7配置adb环境变量的方法
- 如何使python2.7的程序与python3.x的兼容
- [数据库 开发] 大量数据表的优化方案
- 开线程队列下载缓存图片
- bzoj 2661(最大费用流)
- iTunesconnect 缺失Beta版权利
- java中,字符串中的函数的替换方法
- 演进式设计
- leetcode(二)—— Add Two Numbers(Python/C++)
- 用递归法列出硬盘内某一文件夹下的内容。基于Java.io.file
- 详解jQuery中的empty、remove和detach
- JS获取当前浏览器的类型
- VS2013 win7安装提示核心功能严重错误