[小白]poj3487

poj3487

一个稳定匹配问题,利用自己所学的内容写的,有点冗杂,待改进。

代码如下:

```c
#include "stdio.h"
#include "malloc.h"
#include "stdlib.h"
#include "string.h"

#define MAXSIZE   100
#define STACKRE  10
#define OK  1
#define  OVERFLOW -2
#define ERROR   0
#define TRUE  1
#define FALSE  0
#define NUM    100
typedef int Status;
typedef int SElemType;


typedef struct{
	SElemType *base;
	SElemType *top;
	int       stacksize;
}SqStack;

Status InitStack(SqStack &S){    //创建
	S.base = (SElemType *)malloc(MAXSIZE *sizeof(SElemType)) ;

	if(!S.base)
		exit(OVERFLOW);

	S.top= S.base;
	S.stacksize = MAXSIZE;

	return OK;

}

Status Push(SqStack &S,SElemType e){//  插入
	if(S.top -S.base >= S.stacksize){
		S.base = (SElemType *)realloc(S.base,(S.stacksize + STACKRE)*sizeof(SElemType));
		if(!S.base )
			exit(OVERFLOW);

		S.top = S.base + S.stacksize ;
		S.stacksize += STACKRE;
	}

	*S.top++ = e;

	return OK;


}


Status givenumber(SqStack &S, int a[],int n){
	
    int i;
	for(i=0;i<n;i++){
		 Push(S,a[i]);
	
	}
	return OK;


}

Status Pop (SqStack &S,SElemType &e){// 删除栈顶元素
	if(S.top == S.base )
		return ERROR;
	e = *--S.top;
	
	return OK;		
	
}

void dating(SqStack &Stack,int mann,int **boy,int **gril,int* wife,int *count,int *husband,int **invers){
		
		int prefer=boy[mann][count[mann]];//选择未约会排首位的女孩

		if(husband[prefer]== -1){
			husband[prefer]=mann;
			wife[mann]=prefer;//女孩单身,则接受
		}
		else{
			int oldp = invers[prefer][husband[prefer]];
			int newp = invers[prefer][mann];
			if(oldp < newp){
				count[mann]++;
				Push(Stack,mann);//被拒接,加入单身栈
			}
			else{
				count[husband[prefer]]++;//甩掉男友
				Push(Stack,husband[prefer]);//被甩的男友,加入单身栈
				husband[prefer]=mann;
				wife[mann]=prefer;//换男友
			}
		}

		
	}

int main(){
	
	SqStack Stack; //单身男孩的栈
	InitStack(Stack);

	int testnumber;
	int pnumber,kj;
	int count[100];
	char **boy,**gril;
	int **boy1,**gril1,**inverGril;//将字符数组转换为数字数组
	int i,j;
	int ncs=0;
	char zfbs[100],nanxh[100][100],nvxh[100][100];
	
    scanf("%d",&testnumber);   //输入测试数量

    for(int ix = 0;ix < testnumber;ix++){   //输入几个测试量就循环几次 
        scanf("%d",&pnumber);    //输入男孩(女孩)的数量
        ncs++;
        kj = pnumber+3;
        int *wife1, *husband1;
        char *wife, *husband;

        wife1 = (int *) malloc(sizeof(int) * kj);  // 分配
        husband1= (int *) malloc(sizeof(int) * kj); 
        wife = (char *) malloc(sizeof(char) *kj);  
        husband= (char *) malloc(sizeof(char) * kj);  

        boy = (char**)malloc(sizeof(char*)*kj);//为二维数组分配pnumber行 
        gril=(char**)malloc(sizeof(char*)*kj);
        inverGril = (int**)malloc(sizeof(int*)*kj);
        boy1 = (int**)malloc(sizeof(int*)*kj);
        gril1= (int**)malloc(sizeof(int*)*kj);

        for (i = 0; i < kj; i++){//为每列分配pnumber+1个大小空间 
            boy[i] =(char*)malloc(sizeof(char)*kj); 
            gril[i] = (char*)malloc(sizeof(char)*kj); 
            boy1[i]= (int*)malloc(sizeof(int)*kj); 
            gril1[i] = (int*)malloc(sizeof(int)*kj); 
            inverGril[i]=(int*)malloc(sizeof(int)*kj); 
        } 

        int man;

        for( i =0;i<pnumber*2;i++){
            scanf("%s",&zfbs[i]);//输入男孩和女孩的字母表示
        }

        for(i = 0;i<pnumber;i++)
            scanf("%s",nanxh[i]);

        int i1,j1 ;
        for(i = 0;i<pnumber;i++){
            for(i1=j1 =0;nanxh[i][i1]!='\0';i1++)	
                if(nanxh[i][i1] != ':')
                    nanxh[i][j1++]=nanxh[i][i1];
            nanxh[i][j1]='\0';		
        }
     
        for(i = 0;i<pnumber;i++)
            scanf("%s",nvxh[i]);


        for(i = 0;i<pnumber;i++){
            for(i1=j1 =0;nvxh[i][i1]!='\0';i1++)	
                if(nvxh[i][i1] != ':')
                    nvxh[i][j1++]=nvxh[i][i1];
            nvxh[i][j1]='\0';		
        }

        strncpy(husband,zfbs,pnumber);//将截取后的字母给wife数组

        husband[pnumber]='\0';
        strncpy(wife,zfbs+pnumber,pnumber);//将截取后的字母给boy数组
        wife[pnumber]='\0';
        for(i = 0;i<pnumber;i++){
            strncpy(boy[i],nanxh[i]+0,pnumber+2);//将截取后的喜欢数组给boy
            boy[i][pnumber+2]='\0';}
        for(i = 0;i<pnumber;i++){
            strncpy(gril[i],nvxh[i]+0,pnumber+2);//将截取后的喜欢数组给gril
            gril[i][pnumber+2]='\0';}
        for(i = 0;i<pnumber;i++){//将数组转换为数字数组
            wife1[i]=wife[i]-65;
            husband1[i]=husband[i]-97;
            }

        givenumber(Stack,husband1,pnumber);//单身男孩全部入栈

        for(i=0;i<pnumber;i++){//将数组转换为数字数组
            wife1[i]=-1;
            husband1[i]=-1;
            }
        for(i = 0;i<pnumber;i++){
            for( j =0;j<pnumber+1;j++){
                boy1[i][j] = boy[i][j] - 65;
                gril1[i][j] =gril[i][j] - 97;
            }
        }

        for(i =0;i<pnumber*2;i++){//初始化count数组都是0;
            count[i]=1;
        }
        
        for(i = 1;i<=pnumber;i++){//根据女孩的喜欢列表生成一个喜欢程度列表inversegril
            for(j = 1;j<=pnumber;j++){
                inverGril[i-1][gril1[i-1][j]] = j;
            }
        }

        while(Stack.base != Stack.top){
                Pop(Stack,man);//选取单身男孩man
                dating(Stack,man,boy1,gril1,wife1,count,husband1,inverGril);//与prefer约会
                
        }

     
        for(i = 0;i<pnumber;i++){
        wife[i]=char(wife1[i]+65);
        }
       
        if(ncs>1)
             printf("\n");
      
        for(i = 0;i<pnumber;i++)
             printf("%c %c\n",husband[i],wife[i]);

      
        free(wife);
        wife = NULL;
        free(husband);
        husband = NULL;
        free(wife1);
        wife1 = NULL;
        free(husband1);
        husband1 = NULL;
        for (i = 0; i <kj; i++){ 
            free(gril1[i]);
            free(gril[i]); 
            free(boy[i]); 
            free(boy1[i]);
        } 
        free(gril); 
        gril = NULL;
        free(gril1);
        gril1 = NULL;
        free(boy); 
        boy = NULL;
        free(boy1);
        boy1 = NULL;

    }

    return 0;
   
}

题中所给的是字母表示,很蠢的将它转换为数字再转换回去,但又暂时没想到更好的解决方法,还望大佬提提意见。

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值