数字移动排列
给定一个数列,长度为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;
}
示例


不积小流无以成江河

浙公网安备 33010602011771号