数字移动排列

给定一个数列,长度为M(M为偶数),f(x) = x(即数列M为1,2,3,4.....M)

①将数列第一个元素放到最后

②将数列的1,2交换,3,4交换,....,M-1,M进行交换

 

输入有两行,第一行M, N,M为数列最大值,N为使用方法①②的个数

第二行为N个数字,数字为1或2,分别代表方法①②

输出为一行,输出排列好的数列M

 

输入输出示例

输入

6 3

1 2 1

输出

2 5 4 1 6 3

(该数列是从 123456 > 234561 > 325416 > 254163)

解题思路为遍历方法即1,2数列,是否存在连1,连2,因为我们知道,如果该数列中若存在1111只需要一次移动4个即可,对于连2,如果为偶数个2,则不需移动,如果为奇数个只需要移动一次。若无连1,连2,则直接进行移动,若有连1,2则传送给移动方法进行移动。

#include<iostream>
using namespace std;
void func_1(int *ptr, int num, int N)//将数列前num位移动到数列后
{
	int *tmp = new int[num];
	for(int i=0; i<num; ++i)
		tmp[i] = ptr[i];

	for(int i=0; i<N-num; ++i)
		ptr[i] = ptr[i+num];

	for(int i=N-num; i<N; ++i)
		ptr[i] = tmp[i-N+num];
}
void func_2(int *ptr, int num, int N)//交换
{
	if(num)
	{
		for(int i=0; i<N; i+=2)
		{
			int tmp = ptr[i];
			ptr[i] = ptr[i+1];
			ptr[i+1] = tmp;
		}
	}
}
int func(int N, int M)
{
	int *ptr = new int[M], *ptr_1 = new int[M],*num = new int[N];
	for(int i=0; i<N; ++i)
		num[i] = i+1;

	for(int i=0; i<M; ++i)
		cin>>ptr[i];
	for(int i=0; i<M; ++i)
	{
		int num_2 = 0, num_1 = 0, flag = 0;
		while(ptr[i]==2 && ptr[i]==ptr[i+1] && i<M-1)
		{
			++num_2;
			++i;
			flag = 1;
		}
		while(ptr[i]==1 && ptr[i]==ptr[i+1] && i<M-1)
		{
			++num_1;
			++i;
			flag = 1;
		}
		if(num_2 > 0)
		{
			
		       	func_2(num, (num_2+1)%2, N);
		}
		if(num_1 > 0)
		{
			func_1(num, (num_1+1)%N, N);
		}
		if(flag == 0)
		{
			if(ptr[i] == 1)
				func_1(num, 1, N);
			else
				func_2(num, 1, N);
		}
		

	}

	for(int i=0; i<N; ++i)
		cout<<num[i]<<" ";
	cout<<"\n";
	return 0;
}

int main()
{
	int N, M;
	cin>>N;
	cin>>M;
	func(N, M);
	return 0;
}

 示例

 

 

 

posted @ 2020-09-30 10:36  C_hp  阅读(197)  评论(0编辑  收藏  举报