UVA120 Stacks of Flapjacks pancakes

Posted by karlitosphere on Mon, 24 Jan 2022 18:34:37 +0100

Thematic translation

Here is a stack of pancakes. Please write a program to indicate how to arrange these pancakes from top to bottom according to the radius of the pancakes from small to large. All pancakes have different radii.

To put the pancakes in order, you need to flip the pancakes. The method is to insert a spatula into a stack of pancakes, and then turn over (that is, the pancakes on the spatula will be arranged in the opposite order after turning over). If there are n pancakes in a stack, we define the position of the bottom pancake as 1 and the position of the top pancake as n. When the spatula insertion position is k, the pancake from position K to position n needs to be turned over.

At first, the stack of pancakes was stacked randomly and expressed by the size of the radius. For example: the following 3 stacks of pancakes (the leftmost stack 8 is the radius of the top pancake)

     8           7           2
     4           6           5
     6           4           8
     7           8           4
     5           5           6
     2           2           7

For the leftmost pancake, if we insert the spatula in position 3 (under the pancake with radius of 7), we will get the middle pancake. If we insert the spatula in position 1 (under the pancake with radius of 2), we will get the rightmost pancake.

Input

Each group has a column of test data, which shows the initial state of the stack of pancakes. The integer at the beginning of each column (between 1 and 100) represents the radius of the pancake at the top, and so on. The number of pancakes ranges from 1 to 30. Please refer to Sample Input.

Output

Output 2 columns for each group of test data. The first column is the original stack of pancakes. The second column shows the action of turning the pancakes from small to large. The number represents the position where the spatula is inserted. (0 means completed). If it is already arranged, there is no need to turn over. Please refer to Sample Output.

Sample input and output

Enter #1 copy

1 2 3 4 5
5 4 3 2 1
5 1 2 3 4

Output #1 copy

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

Idea: each time you find the maximum value in the current sequence, find a way to put it at the end of the sequence

When finding the maximum value, there are three situations:

① The maximum value is at the end of the sequence No processing is required. Find the maximum value of the first i-1 numbers

② The maximum value is at the beginning of the sequence Flip the sequence, the maximum value reaches the tail, and then execute ①

③ The maximum value is in a certain position Search and find one by one. After finding it, mark it as i. just flip the i number above, and the maximum value will reach the first part, and then execute ②

We can deal with it recursively

Set f(bottom,maxnum)

Bottom is the number of top bottoms that are not ordered (0 < = bottom < = n-1)

maxnum is the maximum number of elements in the currently unordered list

Open an array s to store data

Reuse s_sort array stores the sorted s, which is convenient for us to find maxnum

Because the maximum value in the current sequence is maxnum = s_sort[bottom] 

Recursive function

int f(int bottom,int maxnum)//Bottom records the actual subscript [0, n-1] at the bottom, and maxnum is the maximum value of the number [0,bottom] not arranged above
{
	if(bottom<=0) return 0;
	if(s[bottom]==maxnum)//Maximum at bottom
	{
		f(bottom-1,s_sort[bottom-1]);//We've already arranged this, and then we'll go on to the top
	}
	else if(s[0]==maxnum)//Maximum at top
	{
		int position =n-bottom;//Calculate the position of the plug If the bottom is n-1, the position to be inserted is n-(n-1)=1 
		
		op.push_back(position);//Put the knife at the bottom and turn it over
		reverse(s,s+bottom+1);
		
		f(bottom-1,s_sort[bottom-1]);
	}
	else
	{
		int i=0;
		while(s[i]!=maxnum) i++;
		
		op.push_back(n-i);
		
		reverse(s,s+i+1);//The maximum is at the top
		
		f(bottom,maxnum);//Direct recursive processing
		
	}
	return 0;
}

Complete code

#include<stdio.h>
#include<iostream>
#include<cstdlib>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
int s[100];//For practical processing
int s_sort[100];//Sort the array s first to find the maximum maxnum
int ans[100];//Used for the final output of original data
int n=0;
vector<int>op;
int f(int bottom,int maxnum)//Bottom records the actual subscript [0, n-1] at the bottom, and maxnum is the maximum value of the number [0,bottom] not arranged above
{
	if(bottom<=0) return 0;
	if(s[bottom]==maxnum)
	{
		f(bottom-1,s_sort[bottom-1]);//You've already arranged this, and then go on to the top
	}
	else if(s[0]==maxnum)//Maximum at top
	{
		int position =n-bottom;//Record the insertion position. For example, the bottom is n-1, N - (n-1) = 1 
		
		op.push_back(position);//Put the knife at the bottom and turn it over
		reverse(s,s+bottom+1);
		
		f(bottom-1,s_sort[bottom-1]);
	}
	else
	{
		int i=0;
		while(s[i]!=maxnum) i++;
		
		op.push_back(n-i);
		
		reverse(s,s+i+1);
		
		f(bottom,maxnum);//When the maximum value reaches the top, you can directly f handle it to reduce code duplication
		
	}
	return 0;
}
int init()
{
	n=0;
	op.clear();
	return 0;
}
int main()
{
	//freopen("uva.txt","r",stdin);
	int x;
	
	while(scanf("%d",&x)!=EOF)
	{
		
		do
		{
			s_sort[n]=x;
			ans[n]=x;
			
			s[n++]=x;
			if(getchar()=='\n') break;
		}while(scanf("%d",&x)!=EOF);
		
		
		sort(s_sort,s_sort+n);
		
		
		f(n-1,s_sort[n-1]);
		
		for(int i=0;i<n;i++)
		{
			printf("%d ",ans[i]);
		}
		printf("\n");
		
		for(int i=0;i<(int)op.size();i++)
		{
			printf("%d ",op[i]);
		}
		printf("0\n");
		
		init();	
	}

	return 0;
}

Topics: Algorithm