Dqs1u. 汉诺塔问题(移动方向记数)
时间限制:1.0s 内存限制:256.0MB 代码提交间隔:3分钟(现在可以提交)
试题来源:蓝桥杯2018国际赛 中文版 Lanqiao 第四题
问题描述
汉诺塔问题是一个经典的数学问题。
给定三根柱子A、B、C,柱子A上按大小顺序放着 n 个大小不同的盘子,最下面的盘子最大,最上面的盘子最小。现在要将所有盘子从柱子A移动到柱子C上,问最少要移动多少次。
答案是最少 2n−1 次。而且要以最少的次数完成移动,只存在一种方案。
比如,当 n=3 时,总共要移动 23−1=7 步:
第1步:最小的盘子从A移到C,记为A→C;
第2步:第2小的盘子从A移到B,记为A→B;
第3步:最小的盘子从C移到B,记为C→B;
第4步:第3小的盘子从A移到C,记为A→C;
第5步:最小的盘子从B移到A,记为B→A;
第6步:第2小的盘子从B移到C,记为B→C;
第7步:最小的盘子从A移到C,记为A→C。
请问,总共有多少次A→B,多少次A→C,多少次B→A,多少次B→C,多少次C→A,多少次C→B?
输入格式
输入的第一行包含一个整数 n。
输出格式
输出六行,每行一个整数。分别表示以上六个问题的答案。
样例输入
3
样例输出
1
3
1
1
0
1
评测用例规模与约定
对于30%的评测用例,1≤n≤10。
对于60%的评测用例,1≤n≤30。
对于所有评测用例,1≤n≤60。
#include
using namespace std;
void tmp(int n,char a,char b,char c,int &ab,int &ac,int &ba,int &bc,int &ca,int &cb)
{
if(n == 1)
{
if(a == 'A' && c == 'B') ab++;
else if(a == 'A' && c == 'C') ac++;
else if(a == 'B' && c == 'A') ba++;
else if(a == 'B' && c == 'C') bc++;
else if(a == 'C' && c == 'A') ca++;
else if(a == 'C' && c == 'B') cb++;
return ;
}
tmp(n - 1,a,c,b,ab,ac,ba,bc,ca,cb);
if (a == 'A' && c == 'B') ab++;
else if (a == 'A' && c == 'C') ac++;
else if (a == 'B' && c == 'A') ba++;
else if (a == 'B' && c == 'C') bc++;
else if (a == 'C' && c == 'A') ca++;
else if (a == 'C' && c == 'B') cb++;
tmp(n - 1,b,a,c,ab,ac,ba,bc,ca,cb);
}
int main()
{
int n;
scanf("%d",&n);
int ab = 0,ac = 0,ba = 0,bc = 0,ca = 0,cb = 0;
tmp(n,'A','B','C',ab,ac,ba,bc,ca,cb);
printf("%d\n%d\n%d\n%d\n%d\n%d",ab,ac,ba,bc,ca,cb);
return 0;
}
帮帮我把
import java.util.Scanner;
public class Test2_6_ztk {
public static void main(String args[]){
int num=1;
int k=0;
int f=0;
int a[]=new int[100];
Scanner in=new Scanner(System.in);
int x=in.nextInt();
if(isPrimeNum(x)==false)
{
System.out.println("该数不是可逆素数");
System.exit(0);
}
else
for(int i=0;;i++){
if(x!=0){
a[i]=x%10;
x=x/10;
num*=10;
k++;
}
else
break;
}
for(int i=0;i<k;i++){
f=f*10+a[i];
}
System.out.println("该数反转后是:"+f);
if(isPrimeNum(f))
{
System.out.println("该数是可逆素数");
}
else
System.out.println("该数不是可逆素数");
}
public static boolean isPrimeNum(int a){//判断是否是素数
if(a<=1)
return false;
for(int i=2 ; i<=Math.sqrt(a) ; i++){
if(a%i==0){
return false;
}
}
return true;
}
}
Java中定义数组的方式:int a[]=new int[100] //a是数组的名字,int是数组中存的类型
判断一个数是否是素数的办法:
public static boolean isPrimeNum(int a){//判断是否是素数
if(a<=1)
return false;
for(int i=2 ; i<=Math.sqrt(a) ; i++){
if(a%i==0){
return false;
}
}
return true;
}
另外Java中的弹出提示框输入及输出
String s= JOptionPane.showInputDialog(null,"请输入三位整数");//输入字符型的数据,如果使用可以进行转换
JOptionPane.showMessageDialog(null,"交换后的正整数的值是:"+e);//输出
望采纳
#include <iostream>
using namespace std;
// 将n个盘子从a移动到c,并统计移动次数
void move(int n, char a, char c, int &cnt_ab, int &cnt_ac, int &cnt_ba, int &cnt_bc, int &cnt_ca, int &cnt_cb) {
if (n == 1) {
if (a == 'A' && c == 'B') cnt_ab++;
if (a == 'A' && c == 'C') cnt_ac++;
if (a == 'B' && c == 'A') cnt_ba++;
if (a == 'B' && c == 'C') cnt_bc++;
if (a == 'C' && c == 'A') cnt_ca++;
if (a == 'C' && c == 'B') cnt_cb++;
return;
}
move(n-1, a, 'C', cnt_ab, cnt_ac, cnt_ba, cnt_bc, cnt_ca, cnt_cb);
move(1, a, c, cnt_ab, cnt_ac, cnt_ba, cnt_bc, cnt_ca, cnt_cb);
move(n-1, 'C', c, cnt_ab, cnt_ac, cnt_ba, cnt_bc, cnt_ca, cnt_cb);
}
int main() {
int n;
cin >> n;
int cnt_ab = 0, cnt_ac = 0, cnt_ba = 0, cnt_bc = 0, cnt_ca = 0, cnt_cb = 0;
move(n, 'A', 'C', cnt_ab, cnt_ac, cnt_ba, cnt_bc, cnt_ca, cnt_cb);
cout << cnt_ab << endl
<< cnt_ac << endl
<< cnt_ba << endl
<< cnt_bc << endl
<< cnt_ca << endl
<< cnt_cb << endl;
return 0;
}