POJ 1920 :Towers of Hanoi

Towers of Hanoi
Time Limit: 3000MS   Memory Limit: 16000K
Total Submissions: 2239   Accepted: 999
Case Time Limit: 1000MS

Description

Surely you have already come across the Towers of Hanoi problem: Wooden disks of different sizes are stacked on three pegs, and initially, all disks are stacked on the same peg sorted by size, with the largest disk at the bottom. The objective is to transfer the entire tower to one of the other pegs, moving only one disk at a time and never putting a larger disk onto a smaller one. 
According to an old myth, the monks at an ancient Tibetian monastery have been trying to solve an especially large instance of this problem with 47 disks for thousands of years. Since this requires at least 247 - 1 moves and the monks started out without a strategy, they messed it all up while still following the rules. Now they would like to have the disks stacked up neatly on any arbitrary peg using the minimum number of moves. But they all took a vow which forbids them to move the disks contrary to the rules. They want to know on which peg they should best stack the disks, and the minimum number of moves needed. 
Write a program that solves this problem for the monks. Your program should also be able to handle any number N (0 < N <= 100 000) of disks. The numbers involved in the computation can become quite large. Because of that, the monks are only interested in the number of moves modulo 1 000 000. 
Example 
The following example can be solved in four moves. 

Input

The first line of the input file hanoi.in consists of the number N (N <= 100000) of disks. The second line consists of three integers s1, s2, s3 with 0 <= s1, s2, s3 <= N and s1+s2+s3 = N, the number of disks on each of the three pegs. Lines three to five each contain the sizes of the disks for one peg. More precisely: 
The (i + 2)-th line of the input file consists of integer numbers mi,1 . . .mi,si with 1 <= mi,j <= N, the sizes of the disks on peg i. The disks are given from bottom to top, thus mi,1 > mi,2 > . . . > mi,si . 
Note that an empty stack is given by an empty line. The set of N disks have different sizes. All numbers are separated by a single space.

Output

The first line of the output file hanoi.out consists of the number d in {1, 2, 3} of the peg onto which the disks can be stacked using the minimum number of moves. The second line consists of the number M of required moves modulo 1 000 000.

Sample Input

7
2 1 4
2 1
3
7 6 5 4

Sample Output

3
4

這個漢諾塔與之前的Hackerrank那道題是有着相當相當大的不同,一開始爲了解決Hakerrank那道題特意做了一下這道題,然後用這個3個柱子的思路去往4個柱子的思路上面套。

總體思路是一致的,都是倒過來想,看最原始的狀態如何能夠到達目標狀態。

當時問題在於3個柱子的拿出來的時候狀態是固定的,即其他比這個小的一定摞在另一個柱子上,而四維的情況下,你是沒有辦法判斷這個狀態的。所以那道題n最多是10,讓你自己去枚舉狀態。

這個題就是從最大的那個盤子開始到目標的盤子,然後其餘比這個小的盤子一定在3個柱子的另外一個空柱子上面,然後這個柱子就作爲下一次的起始柱子了。

代碼:

#pragma warning(disable:4996)
#include <iostream>
#include <functional>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <deque>
#include <set>
#include <map>
using namespace std;
typedef long long ll;

#define INF 0x333f3f3f
#define repp(i, n, m) for (int i = n; i <= m; i++)
#define rep(i, n, m) for (int i = n; i < m; i++)
#define sa(n) scanf("%d", &(n))

const int maxn = 1e5 + 5;
const ll mod = 1000000;
const double PI = acos(-1.0);

int n;
int num[5], pos[maxn], val[maxn];

void solve()
{
	int i, j, k;

	sa(num[1]), sa(num[2]), sa(num[3]);

	repp(i, 1, 3)
	{
		repp(j, 1, num[i])
		{
			sa(k);
			pos[k] = i;
		}
	}
	val[0] = 1, val[1] = 2;
	repp(i, 2, n)
	{
		val[i] = (val[i - 1] << 1) % mod;
	}
	int temp = pos[n - 1], last = pos[n];
	int res = 0;
	for (i = n - 1; i > 0; i--, temp = pos[i])
	{
		if (last != temp)
		{
			res = (res + val[i - 1]) % mod;
			last = 6 - last - pos[i];
		}
	}
	printf("%d\n%d\n", pos[n], res);
}

int main()
{
#ifndef ONLINE_JUDGE  
	freopen("i.txt", "r", stdin);
	freopen("o.txt", "w", stdout);
#endif
	
	while (scanf("%d", &n) != EOF)
	{
		solve();
	}
	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章