汉诺塔(四)
时间限制:
3000 ms | 内存限制:
65535 KB
难度:
2
- 描述
-
汉诺塔问题是一个经典的问题,现在我们有 n 个柱子和 m 个编号(1~m)的球,我们现在要求把尽量多的球放在尽量少的柱子上,如果相邻两个球的和不是完全平方数的话球会相互排斥而无法接触。(注意:球必须从小到大放,每次只能放在其他球的上面或者一个新的柱子上面)
- 输入
- 首先一个T,表示T组测试数据,然后一个n(1<=n<=50).
- 输出
- 输出一行,表示n个柱子能放的最大的球编号。
- 样例输入
-
1 4
- 样例输出
-
11
-
相邻两个球的和不是完全平方数的话球会相互排斥而无法接触,也就是说每个柱子最上面两个球的编号相加必须是某个数的平方;
-
在放球的时候,就需要考虑,这个球是否能与一些柱子最上面的球编号组成完全平方数,如果不能就只能把这个球放在新的柱子上。
-
#include<stdio.h> int solve(int n) {//判断n是否为完全平方数 int flag = 0; for(int i = 2; i < n; i++) { if(i * i == n) { flag = 1; break; } } return flag; } int main() { int t; scanf("%d", &t); while(t--) { int n, a[55] = {0}, num, b = 1, count = 0;//a数组存放各个柱子最上面的球号 scanf("%d", &n); for(num = 1; ; num++) {//球号 for(int i = 0; i < n; i++) { if(a[i] == 0) {//如果是个新柱子 a[i] = num;//赋值当前球号 break; } else if(solve(a[i] + num)) {//组成平方数 a[i] = num; //更新该柱子最上面的球号 break; } if(i == n-1) count = num - 1;//已经没有新柱子了,记录能放的最大的球编号 } if(count) break; } printf("%d\n", count); } } //附上公式:(n*n-1)/2+n