uva 10795 A Different Task(递归模拟)

uva 10795 A Different Task

The (Three peg) Tower of Hanoi problem is a popular one in computer science. Briefly the problem is to transfer all the disks from peg-A to peg-C using peg-B as intermediate one in such a way that at no
stage a larger disk is above a smaller disk. Normally, we want the minimum number of moves required for this task. The problem is used as an ideal example for learning recursion. It is so well studied that one can find the sequence of moves for smaller number
of disks such as 3 or 4. A trivial computer program can find the case of large number of disks also.

Here we have made your task little bit difficult by making the problem more flexible. Here the disks can be in any peg initially.

If more than one disk is in a certain peg, then they will be in a valid arrangement (larger disk will not be on smaller ones). We will give you two such arrangements of disks. You will have to find out the minimum number of moves, which will transform the
first arrangement into the second one. Of course you always have to maintain the constraint that smaller disks must be upon the larger ones.

Input

The input file contains at most 100 test cases. Each test case starts with a positive integer
N ( 1N60),
which means the number of disks. You will be given the arrangements in next two lines. Each arrangement will be represented by
N integers, which are 1,
2
or 3. If the i-th (
1iN)
integer is 1, you should consider that i-th disk is on Peg-A. Input is terminated by
N = 0. This case should not be processed.

Output

Output of each test case should consist of a line starting with `Case
#:
‘ where # is the test case number. It should be followed by the minimum number of moves as specified in the problem statement.

Sample Input

3
1 1 1
2 2 2
3
1 2 3
3 2 1
4
1 1 1 1
1 1 1 1
0

Sample Output

Case 1: 7
Case 2: 3
Case 3: 0

题目大意:给出n,表示说有n个大小不同的盘子,然后再给出每个盘子的初始位置和目标位置,要求计算出最少的步数使得每个盘子都移动到它的目标位置。

解题思路:找到需要移动的最大盘子i,然后1~i-1个盘子需要移动到6 - now[i] - end[i],同样的需要让i - 1移动到6 - now[i] - end[i],需要让1~i - 2都移动到 6 -
(6 - now[i] - end[i])- now[i - 1],所以很明显是递归求解,注意要将1~i - 2移动到i - 1上面。

然后进行完上述操作,从1~i-1都在同一个柱子上,可以从大到小将每个碟子还原到目标位置。

#include<stdio.h>
#include<string.h>
int n;
long long begin[65], last[65], num[65];
long long move(int b, int f) {
	if (b < 0) return 0;
	if (begin[b] == f) { //当begin[b] == f时,则b盘子无需移动,其总移动书等于move(b - 1, f)
		return move(b - 1, f);
	}
	else return move(b - 1, 6 - begin[b] - f) + num[b]; //当begin[b] != f时,返回将b - 1个盘子移到中转柱子上的步数 加上 把盘子b移到f柱子上的
                                                                                          //步数(1) 加上 把b - 1个盘子从中转柱子移到f柱子的步数(2^b-1 - 1)
}
long long temp;
long long getAns() {
	long long ans = 0;
	int i;
	for (i = n - 1; i >= 0; i--) {
		if (begin[i] != last[i]) { //找出需要移动的最大盘子
			temp = 6 - begin[i]	- last[i];//中转柱子
			ans += move(i - 1, temp) + 1; //先把i - 1个盘子移到6 - begin[i] - last[i]做中转,然后移动盘子i到final柱子
			i--;
			break;
		}
	}
	for (; i >= 0; i--) {
		if (last[i] != temp) { //若i - 1之后的盘子最终位置不在中转柱子上,将其移到目标柱子上,并修改中转柱子
			temp = 6 - last[i] - temp;
			ans += num[i];
		}
	}
	return ans;
}
int main() {
	int Case = 1;
	while (scanf("%d", &n) == 1, n) {
		memset(begin, 0, sizeof(begin));
		memset(last, 0, sizeof(last));
		memset(num, 0, sizeof(num));
		for (int i = 0; i < n; i++) {
			scanf("%lld", &begin[i]);
		}
		for (int i = 0; i < n; i++) {
			scanf("%lld", &last[i]);
		}
		num[0] = 1;
		for (int i = 1; i < 60; i++) {
			num[i] = num[i - 1] * 2;
		}
		printf("Case %d: %lld\n", Case++, getAns());
	}
	return 0;
}
时间: 2024-10-14 06:27:43

uva 10795 A Different Task(递归模拟)的相关文章

Uva 10795 - A Different Task 【模拟】

A Different Task \epsfbox{p10795a.eps} The (Three peg) Tower of Hanoi problem is a popular one in computer science. Briefly the problem is to transfer all the disks from peg-A to peg-C using peg-B as intermediate one in such a way that at no stage a

uva 10795 - A Different Task (递归+状态转移)

题目链接:uva 10795 - A Different Task 思路来源于:点击打开链接 题意: 新汉若塔问题,有n个盘子,放在3个盘子上,给你一个初始状态和一个结束状态,问你最小步数怎样到达. 思路: 递归+状态转移,直接从初态到末态好像不是那么好办,对最大的一块n,首先肯定要把他放在末态的位置上,假设开始在1号位置,要放到3号位置,那么必须先到达这个状态s:1~n-1必须都从大到小放在2上面,然后放n,然后将1~n-1转移到末态,由对称性,也即可以变为末态转移到状态s,那么处理起来就可以

【汉诺塔问题】UVa 10795 - A Different Task

[经典汉诺塔问题] 汉诺(Hanoi)塔问题:古代有一个梵塔,塔内有三个座A.B.C,A座上有64个盘子,盘子大小不等,大的在下,小的在上.有一个和尚想把这64个盘子从A座移到B座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上.在移动过程中可以利用B座,要求打印移动的步骤.如果只有一个盘子,则不需要利用B座,直接将盘子从A移动到C. 如果有2个盘子,可以先将盘子1上的盘子2移动到B:将盘子1移动到c:将盘子2移动到c.这说明了:可以借助B将2个盘子从A移

UVa 10795 - A Different Task

题目大意:给出n,表示说有n个大小不同的盘子,然后再给出每个盘子的初始位置和目标位置,要求计算出最少的步数使得每个盘子都移动到它的目标位置. 分析:  首先找最大不在目标柱子上的盘子K,因为如果最大的盘子在目标柱子上它不需要移动,也不碍事. 因此问题就成了把K移动到目标柱子,把1到(k-1)移动到中转柱子,所以假设K从A移动到B,A只有K,B是空的,C上面是K-1到1,把这个局面称为参考局面.因为移动是对称的,所以从参考局面移到目标局面与目标局面移到参考局面是一样的步数. 所以问题变成答案=从初

UVA 10795 A Different Task(新汉诺塔问题)

 题目大意:就是普通的汉诺塔问题,给出n,表示说有n个大小不同的碟子,然后再给出每个碟子的初始位置和目标位置,要求计算出最少的步数使得每个碟子都移动到它的目标位置. 思路:考虑编号最大的盘子,如果它在初始位置和目标局面在同一根柱子上,那么我们不需要移动它. 由于盘子的移动是可逆的,根据对称性,我们只需要求出初始局面和目标局面移动形成的参考局面的步数之和,然后加一即可. 我们可以写一个函数f(P, i, final)表示已知各盘子初始编号为P,把1,2,3....i移动到final柱子上所需要

uva 12627 - Erratic Expansion(递归求解)

递归的边界条件写的多了--没必要写呢么多的.. 不明白可共同探讨~ #include<cstdio> #include<iostream> #include<cmath> using namespace std; long long dp(int kk,int pos) { int n=kk;int temp=(int)pow(2,n); // printf("%d %d\n",kk,pos); if(kk==0&&pos==1) r

二分图匹配(匈牙利算法) UVA 670 The dog task

题目传送门 1 /* 2 题意:bob按照指定顺序行走,他的狗可以在他到达下一个点之前到一个景点并及时返回,问狗最多能走多少个景点 3 匈牙利算法:按照狗能否顺利到一个景点分为两个集合,套个模板 4 */ 5 #include <cstdio> 6 #include <algorithm> 7 #include <cstring> 8 #include <cmath> 9 #include <vector> 10 using namespace

uva 10881 Piotr&#39;s Ants (模拟)

uva 10881 Piotr's Ants "One thing is for certain: there is no stopping them; the ants will soon be here. And I, for one, welcome our new insect overlords."Kent Brockman Piotr likes playing with ants. He has n of them on a horizontal pole L cm lo

UVA 10881 - Piotr&#39;s Ants【模拟+思维】

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1822 题意:有很多只蚂蚁在一条直线上,每个蚂蚁移动速度都是1,并且有一个初始方向.并且当相邻两个蚂蚁相撞时转向.现在问t时间后各个蚂蚁的位置. 解法:这题的一个致命技巧就是把两只蚂蚁的相撞看作是两只蚂蚁交换穿过对方并且交换蚂蚁的编号.这个是很好理解的,类似于物理的完全弹性碰撞.又由