2020 Winter Holiday [gmoj1597] [GDKOI2004] [Hanoi Tower Hanoi] [Hanuo Tower Problem]

Title description

The old Hanoi tower problem is this: move the N disks with unequal radii from No. 1 column to No. 3 column with the minimum number of steps. During the movement, the small disk must always be in the large market Above. Now add one more condition: it is not allowed to move the disk directly from No. 1 column to No. 3 column, nor is it allowed to move the disk directly from No. 3 column to No. 1 column. Number the disks from 1 to N according to the radius from small to large. Each state is represented by N integers, and the i-th integer represents the number of the column where the dial i is located. Then the moving scheme when N = 2 is: (1,1) => (2,1) => (3,1) => (3,2) => (2,2) => (1,2) => (1,3) => (2,3) => (3,3) The initial state is the 0th step, program to find the state at a certain number of steps.

Input

The first line of the input file is an integer T (1 <= T <= 50000), indicating the number of groups of input data. In the next T lines, each line has two integers N, M (1 <= n <= 19,0 <= M <= the number of steps required to move N discs).

Output

The output file has T lines. For each set of input data, outputting N integers indicates the state of moving N disks in M ​​steps. Each two numbers are separated by a space, and there should be no extra spaces at the beginning and end of the line.

Sample input

4
2 0
2 5
3 0
3 1

Sample output

1 1
1 2
1 1 1
2 1 1

analysis

This is a regular problem.
It can be found that the movement of the first disc is 1,2,3,3,2,1. Then the second set is 1,1,1,2,2,2,3,3,3,2,2,2,1,1,1. And so on: the number of times of each i-th disk is 3 i-1 . Enumerate 1 ~ n to get it. Time complexity O (n * t).
Finding patterns is very easy ...

Code on

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int t,n,m,a[6]={1,2,3,3,2,1};//a数组从0开始存 
int main()
{
	freopen("hanoi.in","r",stdin);
	freopen("hanoi.out","w",stdout);
    cin>>t;
    for(int i=1;i<=t;i++)
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n-1;i++)
    	{
    		printf("%d ",a[m%6]);
    		m/=3;//每次变化持续长度
		}
		cout<<a[m%6];
		printf("\n");
	}
	fclose(stdin);
	fclose(stdout);
    return 0;
}

Published 110 original articles · 100 praises · 8014 visits

Guess you like

Origin blog.csdn.net/dglyr/article/details/105057483