题目大意
给定一组数,不告诉有多少元素的那种,而且不限行数。比如:
1 2 3 4 5
5 4 3 2 1
5 1 2 3 4
以上就是输入的三组数据,问题是选定一个数,在这个数及之前进行反转,问需反转多少次就能使这组数顺序。比如对于以上数据的答案是:
0
1 0
1 2 0
其中0是结尾。一组数的元素个数为1<=n<=30。每个元素都是整形。
思路
先对原数组a进行排序得到一个有序数组b,都a数组的末尾p开始,如果该数的位置和在b数组中的位置一致(a[p]==b[p])则不需要反转,否则,就向前找到a[i]=b[p],然后将0–i进行反转,使得a[0–i]变成a[i–0],然后再将a[i—p]经行反转,使得a[p]==b[p],注意这里的i必须大于1,等于i=1时无法反转。数据范围不大,直接暴力即可。
反思
这题标签是构造题,用到选择排序的思想,然后又回去补了选择排序的知识感觉简化后就是冒泡排序。然而感觉这个题是个有一定思维的模拟题。不过在做题的时候也有搜索的想法,一查果然有人用IDA*和迭代加深搜索来做。不过这里就不展开了,当作构造题来做了。
代码
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAXN=50;
int a[MAXN],b[MAXN];
int num=1;
int main()
{
//freopen("1.txt","r",stdin);
//freopen("2.txt","w",stdout);
while(scanf("%d",&a[num])!=EOF){
while(getchar()!='\n'){
num++;
scanf("%d",&a[num]);
}
for(int i=1;i<=num;i++) {
b[i]=a[i];
printf("%d",a[i]);
if(i!=num)printf(" ");
}
printf("\n");
sort(b+1,b+1+num);
for(int i=num;i>=1;i--){
if(a[i]!=b[i]){ //不在排好序的位置
for(int j=i-1;j>=1;j--){
if(a[j]==b[i]){
if(j!=1){
printf("%d ",num-j+1);
for(int k=1;k<=j/2;k++) swap(a[k],a[j+1-k]);
}
for(int j=1;j<=i/2;j++) swap(a[j],a[i+1-j]);
printf("%d ",num-i+1);
break;
}
}
}
}
printf("0\n");
memset(a,0,sizeof(a));
num=1;
}
}