数字移动排列
给定一个数列,长度为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; }
示例
不积小流无以成江河