【HDU 1997】汉诺塔VII

本文提供了一种解决汉诺塔VII问题的方法,通过分析盘子移动规律,使用数组存储状态,实现对任意盘子数量的中间状态判断。代码采用C++实现,详细解释了奇偶数盘子时的规律。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

汉诺塔VII(题目链接)

思路

本文参考了下列文章

  • 首先用数组将每一个样例的状态存储

    • 数组的每一行存储一个柱子的状态
    • 每一行的第0列存储柱子上盘子的数目
    • 其后从下到上存储柱子对应位置上的盘子的编号
  • 使用函数根据在移动盘子的过程中的规律判断

    • 当盘子的数目为奇数时,在移动过程中,第奇数个柱子的最低位置上的盘子编号为奇数
    • 当盘子的数目为偶数时,则相反
    • 并且每一个柱子上的盘子的编号必定交替出现

代码

#include <iostream>
using namespace std;

//存储输入的状态,tab[i][0]表示第i个柱子上的盘子数目,后面依次为盘子的编号 
int tab[3][65];

//判断tab中的状态是不是移动n个盘子时的中间状态 
int f(int n){										//输入为盘子的数目 
	for(int i = 0; i < 3; ++i){						//分别判断三个柱子 
		if(0 == tab[i][0]){							//若该柱子没有盘子 
			continue;								//直接判断下一个柱子 
		}
		//奇数个盘子时在第奇数个柱子的最下面的盘子的编号为奇数,偶数相反 
		if((n+i) % 2 != tab[i][1] % 2){				//若不相同 
			return 0;								//直接返回false 
		}
		//每个柱子上的盘子编号应该是奇偶数交替 
		for(int j = 2; j <= tab[i][0]; ++j){		//循环柱子上的每一个盘子 
			if((tab[i][j-1]+tab[i][j]) % 2 == 0){	//若编号不是交替 
				return 0;							//直接返回false 
			}
		}		
	}
	return 1;										//条件满足,返回true 
}

int main(){
	int t, n;										//定义变量 
	cin >> t;										//输入样例数 
	while(t--){										//循环t次 
		cin >> n;									//输入盘子数目
		//输入柱子上的盘子状态				 
		for(int i = 0; i < 3; ++i){					//循环 
			cin >> tab[i][0];						//输入柱子上盘子数目 
			for(int j = 1; j <= tab[i][0]; ++j){	//循环 
				cin >> tab[i][j];					//输入柱子上的盘子编号
			}
		}
		if(f(n)){									//若返回为 1 
			cout << "true" << endl;					//输出true 
		}else{										//否则 
			cout << "false" << endl;				//输出false 
		}
	}
	
	
	return 0;
} 

总结

当看到题目时,基本的模拟做出来了之后,应该仔细思考看看有没有什么规律

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值