又是汉诺塔~

回顾一下汉诺塔的移动过程。

从左到右设为A,B,C  3个盘子的时候

1: No.1  A -> C

2: No.2  A -> B

3: No.1  C -> B

4: No.3  A -> C

5: No.1  B -> A

6: No.2  B -> C

7: No.1  A -> C

.把第n个盘子移动到C前,第n-1个盘子要移动到B。也就是说,此时,如果第n-1个盘子在 C就是错误的,而第n个盘子在B就是错误的。那么就可以进行递归判断。调用check(intn,int A,int B,int C) A为移动的起点,C为终点。此时的盘子只能在A或者C上。

若n在A上,那么第n-1个要么在B上要么在A上,绝不可能在C上。换句话说,此时起点应该为A,而终点为B。所以调用改为:check(n-1,A,C,B);

若n在C上,那么第n-1 要么在B上,要么在C上,绝不可能在A上,换句话说,此时起点应该为B,而终点为C。 check(n-1,B,A,C);

#include <cstdio>
#include <cstring>
const int MAXN=64+10;
int a[4][MAXN],cur[4];
bool flag;
void check(int n,int A,int B,int C)
{
if(n==0) { flag=true; return ;}
if(a[A][cur[A]]==n)
{
cur[A]++;
check(n-1,A,C,B);
}
else if(a[C][cur[C]]==n)
{
cur[C]++;
check(n-1,B,A,C);
}
else { flag=false; return ;}
}
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
memset(a,0,sizeof(a));
int n;
scanf("%d",&n);
for(int i=1;i<=3;i++)
{
scanf("%d",&a[i][0]);
for(int j=1;j<=a[i][0];j++)
scanf("%d",&a[i][j]);
}
cur[1]=cur[2]=cur[3]=1;
flag=false;
check(n,1,2,3);
if(flag)
printf("true\n");
else
printf("false\n");
}
return 0;
}

最新文章

  1. tomcat不安全因素
  2. VS2010 AppCode文件夹问题
  3. 第7章 jQuery插件的使用和写法
  4. supervisor、pm2、forever坐下来聊聊
  5. (转载)解决ListView中使用EditText所遇到的一些冲突
  6. sql遍历树
  7. 如何判断ios设备是否是高清屏幕
  8. 使用C#开发纽曼USB来电小秘书客户端小结
  9. [编织消息框架][JAVA核心技术]动态代理应用5-javassist
  10. 表连接查询(2-n)
  11. CLR,GC 表示什么意思?
  12. Flex自定义组件、皮肤,并调用
  13. 消除游戏源码 Match 3 Jewel Full 298 Levels
  14. 【java】关于Map的排序性的一次使用,有序的Map
  15. java webservice maven spring Class Not Found Exception解决
  16. 使用jquery处理数据时要注意的问题
  17. 扩展javascript原生对象
  18. Centos 7 smb 安装使用
  19. 第一百四十八节,封装库--JavaScript,菜单切换
  20. 小苏的Shell编程笔记之六--Shell中的函数

热门文章

  1. 用YourAPP开发网络状态提醒应用
  2. POJ 2437 贪心+priority_queue
  3. Kinect 开发 —— 常见手势识别(上)
  4. touch---创建文件或更改文件日期
  5. Django模型三
  6. C# XML类学习整理(待补)
  7. POJ 2828 线段树单点更新 离线搞
  8. 结构体类型重声明导致的bug一个
  9. ubuntu网络重启后或主机重启后,/etc/resolv.conf恢复原样的解决办法
  10. [NowCoder]牛客OI周赛3