南理工2016考研复试上机题男女程序员排队
2018-06-17 21:16:18来源:未知 阅读 ()
题目:
输入一个由男女程序员组成的序列FFMMFMMMFF,现要通过适当的交换操作让女程序员全部排在男程序员前面,即使原序列变成FFFFFMMMMM,问至少需要交换多少次,交换次数最少的交换操作是什么?
1 #include <stdio.h> 2 #include <malloc.h> 3 #define MALE 5 //队列中男程序员位数 4 #define FEMALE 5 //队列中女程序员位数 5 struct swap //记录交换操作的结构体类型 6 { 7 int k; //右交换下标 8 int i; //左交换下标 9 struct swap *next; //后继指针 10 struct swap *front; //前驱指针 11 }; 12 typedef struct swap swap1; 13 14 struct image //保存找到的交换操作序列的结构体类型 15 { 16 int k; //右交换下标 17 int i; //左交换下标 18 struct image *next; 19 }; 20 typedef struct image image1; 21 int number(int i, char que[]); //函数,寻找当前序列索引下标i后的第一位女程序员下标,找到返回下标,没有找到返回-1 22 void copy(swap1 *head, image1 *head1); //释放head1指向的线性链表,并将head指向的交换序列链表拷贝至链表head1中 23 24 void main() 25 { 26 int start; //从队列开头起连续排列的女程序员序列中最后一位女程序员下标,若队列第一位是男程序员,start为-1 27 char que[MALE+FEMALE]; //存放男女程序员队列的数组,字符'0'代表男程序员,'1'代表女程序员 28 printf("输入男女程序员序列,0男1女\n"); //输入男女程序员序列 29 scanf("%s", que); 30 31 start=0; 32 while(que[start]!='0') 33 { 34 if (que[start]=='0') //确定从队列开头起连续排列的女程序员序列中最后一位女程序员下标 35 break; 36 start++; 37 } 38 start-=1; 39 40 if (start==FEMALE-1) //女程序员已全部放到男程序员前面,无需交换 41 { 42 printf("最小交换次数为0\n"); 43 } 44 else 45 { 46 swap1 *head, *psnew, *before, *after; //after指向head链表最后一个结点,before指向倒数第二个 47 image1 *head1, *psnew1; 48 int i, k, count, flag, minswap; //i为回溯过程中前进深度,任何时候下标i及i前面下标位置的元素均为女程序员,k为在某下标之后找到的第一位女程序员标号 49 char temp; //count用于统计交换次数,minswap为最小交换次数 50 bool TF; //TF为true表示从上一轮回溯至本轮,为false表示从上一轮前进至本轮 51 head=(swap1 *) malloc(sizeof(swap1)); //初始化交换序列链表,用于保存找到的可行交换序列 52 head->next=NULL; 53 head->front=NULL; 54 before=head; 55 after=head; 56 57 head1=(image1 *) malloc(sizeof(image1)); //初始化head1链表,用于保存交换次数最少的交换序列 58 head1->next=NULL; 59 60 i=start; 61 TF=false; 62 count=0; 63 flag=0; 64 65 while (1) 66 { 67 if (i==start) //从start处开始试探 68 { 69 if (TF==false) //第一次试探 70 { 71 k=number(i, que); 72 } 73 else 74 { 75 k=number(k, que); 76 if (k==-1) //在start处已无法找到下一个可交换女程序员,试探结束 77 break; 78 } 79 80 temp=que[i+1]; 81 que[i+1]=que[k]; //找到可交换女程序员k,交换i+1,,和k 82 que[k]=temp; 83 count++; 84 psnew=(swap1 *) malloc(sizeof(swap1)); 85 psnew->k=k; 86 psnew->i=i+1; //交换操作(i+1, k)加入链表 87 psnew->next=NULL; 88 after->next=psnew; 89 psnew->front=after; 90 before=after; 91 after=psnew; 92 i++; //递进至下一层 93 TF=false; 94 } 95 else 96 { 97 if (TF==false) //进至新的一层i>start,从i后开始寻找第一个女程序员位置 98 k=number(i, que); 99 else 100 k=number(k, que); //回溯至本层,从上一次找到的女程序员位置后寻找第一个女程序员 101 102 if (k==-1) 103 { 104 if (TF==false) 105 { 106 if (flag==0) //所有女程序员均已排到男程序员前面,判断flag值,比较count以决定是否更新count和head1链表 107 { 108 copy(head, head1); 109 minswap=count; 110 flag=1; 111 } 112 else 113 { 114 if (minswap>count) 115 { 116 copy(head, head1); 117 minswap=count; 118 } 119 } 120 } 121 122 k=after->k; //找到最后一轮交换操作(i,k) 123 i=after->i; 124 temp=que[i]; 125 que[i]=que[k]; //,回溯交换que[i],que[k] 126 que[k]=temp; 127 count--; 128 free(after); 129 before->next=NULL; //删掉head链表尾节点 130 after=before; 131 before=before->front; 132 i--; //回溯至上一层 133 TF=true; 134 } 135 else 136 { 137 if (k!=i+1) //进入本层时TF==false,此时从i后寻找第一个女程序员下标,由于找到的女程序员要和i+1位置交换 138 { 139 temp=que[i+1]; //所以,若该女程序员就位于i+1位置,该段语句不执行,否则就应 140 que[i+1]=que[k]; //将找到的女程序员k和i+1交换,并将交换操作放入head链表 141 que[k]=temp; 142 count++; 143 psnew=(swap1 *) malloc(sizeof(swap1)); 144 psnew->k=k; 145 psnew->i=i+1; 146 psnew->next=NULL; 147 after->next=psnew; 148 psnew->front=after; 149 before=after; 150 after=psnew; 151 } 152 i++; //递进至下一层 153 TF=false; 154 } 155 } 156 } 157 printf ("把女程序员交换至最前面所需最小交换次数为%d\n", minswap); //输出最小交换次数 158 printf("交换次数最小的交换方式为:\n"); 159 i=start+1; 160 for (psnew1=head1->next; psnew1!=NULL; psnew1=psnew1->next) //输出交换操作 161 { 162 printf("交换序列中第%d个和第%d个程序员\n", psnew1->i+1, psnew1->k+1); 163 } 164 } 165 } 166 167 int number(int i, char que[]) 168 { 169 for (int j=++i; j<MALE+FEMALE; j++) 170 { 171 if (que[j]=='1') 172 return j; 173 } 174 175 return -1; 176 } 177 178 void copy(swap1 *head, image1 *head1) 179 { 180 image1 *p, *tail; 181 swap1 *psnew; 182 183 while(head1->next!=NULL) //释放head1链表 184 { 185 p=head1->next; 186 head1->next=p->next; 187 free(p); 188 } 189 190 tail=head1; 191 for (psnew=head->next; psnew!=NULL; psnew=psnew->next) 192 { 193 p=(image1 *) malloc(sizeof(image1)); //拷贝 194 p->k=psnew->k; 195 p->i=psnew->i; 196 p->next=NULL; 197 tail->next=p; 198 tail=p; 199 } 200 }
运行结果:
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
下一篇:蚂蚁问题的一个小扩展
- 2020年3月28日UCF Local Programming Contest 2016 2020-03-31
- 洛谷P4071-[SDOI2016]排列计数 题解 2020-01-12
- [NOIP2016]天天爱跑步-题解 2019-10-08
- CSP201612-2:工资计算 2018-09-05
- CSP201604-2:俄罗斯方块 2018-09-01
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash