南理工2016考研复试上机题男女程序员排队

来源:互联网 发布:excel 数据清洗 编辑:程序博客网 时间:2024/05/16 02:12

题目:

输入一个由男女程序员组成的序列FFMMFMMMFF,现要通过适当的交换操作让女程序员全部排在男程序员前面,即使原序列变成FFFFFMMMMM,问至少需要交换多少次,交换次数最少的交换操作是什么?

#include <stdio.h>#include <malloc.h>#define MALE 5   //队列中男程序员位数#define FEMALE 5 //队列中女程序员位数struct swap    //记录交换操作的结构体类型{   int k;      //右交换下标   int i;      //左交换下标   struct swap *next;  //后继指针   struct swap *front; //前驱指针};typedef struct swap swap1;struct image  //保存找到的交换操作序列的结构体类型{int k;    //右交换下标int i;    //左交换下标struct image *next;};typedef struct image image1;int number(int i, char que[]);   //函数,寻找当前序列索引下标i后的第一位女程序员下标,找到返回下标,没有找到返回-1void copy(swap1 *head, image1 *head1);    //释放head1指向的线性链表,并将head指向的交换序列链表拷贝至链表head1中void main(){   int start;  //从队列开头起连续排列的女程序员序列中最后一位女程序员下标,若队列第一位是男程序员,start为-1   char que[MALE+FEMALE];     //存放男女程序员队列的数组,字符'0'代表男程序员,'1'代表女程序员   printf("输入男女程序员序列,0男1女\n");    //输入男女程序员序列   scanf("%s", que);   start=0;   while(que[start]!='0')   {   if (que[start]=='0')   //确定从队列开头起连续排列的女程序员序列中最后一位女程序员下标   break;   start++;   }   start-=1;   if (start==FEMALE-1)    //女程序员已全部放到男程序员前面,无需交换   {   printf("最小交换次数为0\n");   }   else   {   swap1 *head, *psnew, *before, *after;  //after指向head链表最后一个结点,before指向倒数第二个   image1 *head1, *psnew1;   int i, k, count, flag, minswap;  //i为回溯过程中前进深度,任何时候下标i及i前面下标位置的元素均为女程序员,k为在某下标之后找到的第一位女程序员标号   char temp;                       //count用于统计交换次数,minswap为最小交换次数   bool TF;                         //TF为true表示从上一轮回溯至本轮,为false表示从上一轮前进至本轮   head=(swap1 *) malloc(sizeof(swap1));    //初始化交换序列链表,用于保存找到的可行交换序列   head->next=NULL;   head->front=NULL;   before=head;   after=head;   head1=(image1 *) malloc(sizeof(image1));   //初始化head1链表,用于保存交换次数最少的交换序列   head1->next=NULL;   i=start;   TF=false;   count=0;   flag=0;   while (1)   {   if (i==start) //从start处开始试探   {   if (TF==false)  //第一次试探   {   k=number(i, que);     }   else   {   k=number(k, que);   if (k==-1)    //在start处已无法找到下一个可交换女程序员,试探结束   break;   }   temp=que[i+1];   que[i+1]=que[k];   //找到可交换女程序员k,交换i+1,,和k   que[k]=temp;   count++;   psnew=(swap1 *) malloc(sizeof(swap1));   psnew->k=k;   psnew->i=i+1;         //交换操作(i+1, k)加入链表   psnew->next=NULL;   after->next=psnew;   psnew->front=after;   before=after;   after=psnew;   i++;                //递进至下一层   TF=false;   }   else   {   if (TF==false)      //进至新的一层i>start,从i后开始寻找第一个女程序员位置   k=number(i, que);   else   k=number(k, que);   //回溯至本层,从上一次找到的女程序员位置后寻找第一个女程序员   if (k==-1)   {   if (TF==false)   {   if (flag==0)        //所有女程序员均已排到男程序员前面,判断flag值,比较count以决定是否更新count和head1链表   {   copy(head, head1);   minswap=count;   flag=1;   }   else   {   if (minswap>count)   {   copy(head, head1);   minswap=count;   }   }   }   k=after->k;  //找到最后一轮交换操作(i,k)   i=after->i;   temp=que[i];       que[i]=que[k]; //,回溯交换que[i],que[k]       que[k]=temp;   count--;                   free(after);   before->next=NULL;   //删掉head链表尾节点   after=before;   before=before->front;   i--;    //回溯至上一层   TF=true;   }   else   {   if (k!=i+1)    //进入本层时TF==false,此时从i后寻找第一个女程序员下标,由于找到的女程序员要和i+1位置交换   {       temp=que[i+1];    //所以,若该女程序员就位于i+1位置,该段语句不执行,否则就应           que[i+1]=que[k];  //将找到的女程序员k和i+1交换,并将交换操作放入head链表           que[k]=temp;           count++;           psnew=(swap1 *) malloc(sizeof(swap1));           psnew->k=k;   psnew->i=i+1;           psnew->next=NULL;           after->next=psnew;           psnew->front=after;           before=after;           after=psnew;   }       i++;    //递进至下一层       TF=false;   }   }   }   printf ("把女程序员交换至最前面所需最小交换次数为%d\n", minswap);    //输出最小交换次数   printf("交换次数最小的交换方式为:\n");   i=start+1;   for (psnew1=head1->next; psnew1!=NULL; psnew1=psnew1->next)    //输出交换操作   {   printf("交换序列中第%d个和第%d个程序员\n", psnew1->i+1, psnew1->k+1);   }   }}int number(int i, char que[]){for (int j=++i; j<MALE+FEMALE; j++){if (que[j]=='1')return j;}return -1;}void copy(swap1 *head, image1 *head1){image1 *p, *tail;swap1 *psnew;while(head1->next!=NULL)    //释放head1链表{p=head1->next;head1->next=p->next;free(p);}tail=head1;for (psnew=head->next; psnew!=NULL; psnew=psnew->next){p=(image1 *) malloc(sizeof(image1));   //拷贝p->k=psnew->k;p->i=psnew->i;p->next=NULL;tail->next=p;tail=p;}}

运行结果: