问题描述:假定在一舞会上,男士排成一队,女士排成一队。跳舞开始时,依次从男队和女队的队头各出一人配成舞伴。若两队初始人数不相同,则较长的那一队中未配对者等待下一轮舞曲。要求:模拟上述舞伴系统,并能计算对于任何男士A和女士B在哪一轮舞曲中的k次跳舞?
设计思路:
首先,由于当男女排好队后,依次从男队和女队的队头上各出一人配成舞伴,剩下的人继续按顺序配对,具有典型的先进先出特性,因此可以用队列作为算法的数据结构。
在算法中应该先设置两个队列:man (pm),woman(pw)分别存放男士和女士入队者。假设男士和女士的信息存放在一位数组中,作为输入,然后依次扫描该数组各元素,并根据性别来决定是进入男队还是女队。构造好两个队列后,依次将两队队头元素出队来匹配成舞伴,直至某队列变为空,此时若某队仍有待匹配者,输出等待者的名字。
其次,采用二维数组的行表示跳舞的轮数,列表示跳舞的次数。可以实现查询某位男生和某位女生在第几轮的K次跳舞。
代码:
#include <stdio.h>
#include<stdlib.h>
void dancingQueue(int m,int n,int a,int b){
if(m<=0||n<=0){//人数输入错误,直接返回
printf("输入错误\n");
}
int* men=(int*)malloc(sizeof(int)*m);//男生队列
int* women=(int*)malloc(sizeof(int)*n);//女生队列
int i,j;
//初始化男生和女生队列,编号等同于下标
for(i=0;i<m;i++){
men[i]=i;
}
for(i=0;i<n;i++){
women[i]=i;
}
int pm=0,pw=0;//男生出队指针pm,女生出队指针pw
int max=m>n?m:n;
int pmax=max;//男女生人数较大值
int pmin=m<n?m:n; //男女生人数较少值
int arr[pmax][pmin];//辅助数组,行数代表轮数,列数代表一轮匹配对数
//初始化辅助空间
for(i=0;i<pmax;i++){
for(j=0;j<pmin;j++){
if(m>n){
arr[i][j]=men[pm];
pm=(pm+1)%m;
}else{
arr[i][j]=women[pw];
pw=(pw+1)%n;
}
}
}
//输出匹配情况
while(max--){//两队列中人数较多的值决定跳舞轮数
int min=m<n?m:n;
printf("第%d轮配对情况:\n",pmax-max);//输出轮数
while(min--){//两队列中人数较少的值决定每轮跳舞的次数
printf("男生%d号-----女生%d号\n",men[pm],women[pw]);//输出每轮男女生匹配情况
pm=(pm+1)%m;//男生队列循环
pw=(pw+1)%n;//女生队列循环
}
}
printf("\n\n");
//寻找男生a和女生b的配对情况
if(a>=m||b>=n){
printf("输入男生女生编号错误");
} else{
int pa=a,pb=b;
for(i=0;i<pmax;i++){
for(j=0;j<pmin;j++){
if(m<n){
if((arr[i][j]==pb)&&j==pa){
printf("第%d轮第%d次,男生%d会和女生%d跳舞\n",i+1,j+1,pa,pb);
}
}else{
if((arr[i][j]==pa)&&j==pb){
printf("第%d轮第%d次,男生%d会和女生%d跳舞\n",i+1,j+1,pa,pb);
}
}
}
}
}
}
int main(){
int m,n,a,b;
printf("请输入男生人数和女生人数:");
scanf("%d%d",&m,&n);//男生人数m,女生人数n
printf("请输入男生编号和女生编号:");
scanf("%d%d",&a,&b);// 要查询的男生编号a,女生编号b
dancingQueue(m,n,a,b);
return 0;
}
