HDU1997 汉诺塔7

来源:互联网 发布:mv制作软件 编辑:程序博客网 时间:2024/06/07 13:43

汉诺塔VII

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1429    Accepted Submission(s): 934


Problem Description
n个盘子的汉诺塔问题的最少移动次数是2^n-1,即在移动过程中会产生2^n个系列。由于发生错移产生的系列就增加了,这种错误是放错了柱子,并不会把大盘放到小盘上,即各柱子从下往上的大小仍保持如下关系 :
n=m+p+q
a1>a2>...>am
b1>b2>...>bp
c1>c2>...>cq
ai是A柱上的盘的盘号系列,bi是B柱上的盘的盘号系列, ci是C柱上的盘的盘号系列,最初目标是将A柱上的n个盘子移到C盘. 给出1个系列,判断它是否是在正确的移动中产生的系列.
例1:n=3
3
2
1
是正确的
例2:n=3
3
1
2
是不正确的。
注:对于例2如果目标是将A柱上的n个盘子移到B盘. 则是正确的.
 

Input
包含多组数据,首先输入T,表示有T组数据.每组数据4行,第1行N是盘子的数目N<=64.
后3行如下
m a1 a2 ...am
p b1 b2 ...bp
q c1 c2 ...cq
N=m+p+q,0<=m<=N,0<=p<=N,0<=q<=N,
 

Output
对于每组数据,判断它是否是在正确的移动中产生的系列.正确输出true,否则false
 

Sample Input
631 31 21 131 31 11 263 6 5 41 12 3 263 6 5 42 3 21 131 31 21 1202 20 172 19 1816 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
 

Sample Output
truefalsefalsefalsetruetrue


两种做法,一种模拟法一种找规律

模拟法的话

   n号盘子只可能在A或C上。

n在A上这个时候n-1号盘一定在A或B上

n在C上这个时候n-1号一定在B或C上

往上递归这两个过程

找规律的话

可以利用n号盘和n-1号盘之间的关系建立一个

奇偶关系的限制。

盘为奇数时,最底为偶数的只能在2号柱,底数为奇数的盘只能在1,3号柱
偶数与上面相反每一根柱子上的盘是奇偶互换的



模拟法的代码

#include<cstdio>#define maxn 70using namespace std;int a[4][maxn],t,n;bool han(int k,int s,int z,int e){  if(k<1)return 1;  int s1=a[s][0],s2=a[z][0],s3=a[e][0];  if(a[s][s1]==k)    {      a[s][0]--;      return han(k-1,s,e,z);    }  if(a[e][s3]==k)    {      a[e][0]--;      return han(k-1,z,s,e);    }  return 0;  }void work(){  int i,j,k;  bool flag;  while(scanf("%d",&t)==1)    for(j=1;j<=t;j++)      {        scanf("%d",&n);        scanf("%d",&a[0][0]);        for(i=a[0][0];i>=1;i--)scanf("%d",&a[0][i]);        scanf("%d",&a[1][0]);        for(i=a[1][0];i>=1;i--)scanf("%d",&a[1][i]);        scanf("%d",&a[2][0]);        for(i=a[2][0];i>=1;i--)scanf("%d",&a[2][i]);        if(han(n,0,1,2))printf("true\n");        else printf("false\n");      }}int main(){  work();  return 0;}

找规律代码

#include <iostream>#include <algorithm>#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#define MAX(a,b) ((a)>(b)?(a):(b))#define MIN(a,b) ((a)<(b)?(a):(b))using namespace std;int main(){    int tests,n,i,j,t,flag;    int mem[2];    scanf("%d",&tests);    while(tests--){        flag = 1;        scanf("%d",&n);        for(i=0;i<3;i++){            scanf("%d%d",&t,&mem[0]);            if((n+mem[0]+i)%2) flag = 0;            for(j=1;j<t;j++){                scanf("%d",&mem[j%2]);                if((mem[j%2]-mem[(j-1)%2]-1)%2) flag = 0;            }        }        if(flag) printf("true\n");        else printf("false\n");    }}



0 0
原创粉丝点击