标题:速配游戏---求编码带注释,谢谢
只看楼主
weisx
Rank: 1
来 自:吉林
等 级:新手上路
帖 子:20
专家分:0
注 册:2016-2-29
结帖率:100%
已结贴  问题点数:10 回复次数:4 
速配游戏---求编码带注释,谢谢
【问题描述】
有这么一个速配电视节目。N位男士和N位女士要在摄像机前选出他们合适的伴侣。每位女士按照其对每位男士作为配偶的偏爱程度给每位男士排名次,每位男士也按照其对每位女士作为配偶的偏爱程度给每位女士排名次。这些名次不允许并列。然后每位男士将向心仪的对象求婚,经过"残酷"的竞争之后各自找到适合的伴侣。
最开始的时候每位男士都还没有被任何一位女士拒绝。求婚环节会经过很多轮进行,每一轮:
(1) 每位男士在还没有拒绝过自己的女士中选出自己认为最理想的一个,并向她求婚
(2) 每位女士在所有这一轮中向她求婚的男士中选出自己认为最理想的一个,并不答应,也不拒绝。她把其余向她求婚的男士都婉言拒绝掉。经过了若干轮求婚之后,在某一轮,幸运的事情发生了:所有的女士都恰好有一个求婚者,所有的男士都找到一个心仪的对象。主持人将继续指出这个配对方式的神奇之处:没有任意的两个配对,比方说男士A和女士a配对,男士B和女士b配对,使得在A心目中b较a更理想,而且在b心目中A较B更理想(这样A和b就会"私奔")。因此,主持人总结说,这个配对是非常合理的。(他知道,这种情况是一定会发生的。)
主持人在节目之前已经知道男士和女士之间的偏爱情况,他想预先知道最后的匹配结果是怎么样的,你能帮帮他吗?
【要求】
【数据输入】第一行包括一个数字N(1<=N<=1000)以下N*2行,每行有N个数字。第i+1行(1<=i<=N)表示编号为i的男士对女士们的排序(从最喜欢的到最不喜欢的)。第N+j+1行(1<=j<=N)表示编号为j的女士对男士们的排序(同样从最喜欢的到最不喜欢的)。
【数据输出】N行,每行包括一个数字。第i行的数字表示与编号为i的男士匹配的女士的编号。
【样例输入】
3
1 2 3
2 3 1
2 1 3
3 2 1
2 3 1
2 3 1
【样例输出】
3
2
1
搜索更多相关主题的帖子: 电视节目 摄像机 速配 游戏 男士 
2016-03-03 20:52
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
得分:6 
程序代码:
#include <stdio.h>
#include <stdbool.h>

#define N 3

// 找到 第n位男士当前最中意且未被拒绝过的女士
void findWoman(int sa[N][N], int mostLike[N])
{
    for (int i = 0;i < N;i++)
    {
        int pos = 0, ans = sa[i][0];
        for (int j = 0;j < N;j++)
        {
            if (ans < sa[i][j]) pos = j, ans = sa[i][pos];
        }
        printf("%2d号男士对%2d号女士求婚\n", i + 1, mostLike[i] = pos + 1);
    }
    printf("\n");
}

// 获取当前求婚状态
bool getState(int state[N][N+1], int mostLike[N])
{
    for (int i = 0;i < N;i++)
    {
        state[i][0] = 0;
        for (int j = 0;j < N;j++)
        {
            if (mostLike[j] == i + 1) state[i][++state[i][0]] = j + 1;
        }
    }

    return state[0][0] == 1 && state[1][0] == 1 && state[2][0] == 1;
}

// 根据男士的选择,女士将不是最满意的拒绝
void refuseMan(int sa[N][N], int sb[N][N], int state[N][N+1], int n)
{
    if (state[n - 1][0] == 0)
    {
        printf("当前没有男士对第%2d位女士求婚\n", n);
        return;
    }

    // 找到女士的求婚者中最中意的男士
    int tm = state[n - 1][1];
    int tn = sb[n - 1][tm - 1];
    for (int i = state[n - 1][0];i > 1;i--)
    {
        if (sb[n - 1][state[n - 1][i] - 1] > tn)
        {
            tm = state[n - 1][i];
            tn = sb[n - 1][tm - 1];
        }
    }

    // 将其他男士拒绝
    for (int i = state[n - 1][0];i > 0;i--)
    {
        if (tm != state[n - 1][i])
        {
            printf("%2d号女士拒绝了%2d号男士\n", n, state[n - 1][i]);
            sa[state[n - 1][i] - 1][n - 1] = -1;
        }
    }
}

// 打印最终结果
void print(int state[N][N+1])
{
    for (int i = 0;i < N;i++)
    {
        printf("%2d号男士选择了%2d号女士\n", state[i][1], i + 1);
    }
}

int main()
{
    int sa[N][N] = { { 1, 2, 3 }, { 2, 3, 1 }, { 2, 1, 3 } };
    int sb[N][N] = { { 3, 2, 1 }, { 2, 3, 1 }, { 2, 3, 1 } };

    int mostLike[N] = { 0 };  // a[n]记录当前第n+1位男士最中意的女士
    int state[N][N + 1] = { { 0 } };    // state[n]记录当时会对第n位女士求婚的男士,state[n][0]表示人数

    while (true)
    {
        findWoman(sa, mostLike);

        if (getState(state, mostLike)) break;

        for (int i = 0;i < N;i++)
        {
            refuseMan(sa, sb, state, i + 1);
        }
    }
    print(state);
    return 0;
}


[此贴子已经被作者于2016-3-5 01:43编辑过]



[fly]存在即是合理[/fly]
2016-03-04 18:06
weisx
Rank: 1
来 自:吉林
等 级:新手上路
帖 子:20
专家分:0
注 册:2016-2-29
得分:0 
回复 2楼 azzbcc
我用vc6.0运行不了,有一处错误,显示头文件#include <stdbool.h>出错
2016-03-05 22:29
qq1023569223
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:湖南科技大学
等 级:贵宾
威 望:26
帖 子:2753
专家分:13404
注 册:2010-12-22
得分:4 
回复 3楼 weisx
每种编译器不一样,像我的Code::Blocks如果用到bool就要stdbool.h。你可以去掉#include <stdbool.h>试试。

   唯实惟新 至诚致志
2016-03-05 22:34
weisx
Rank: 1
来 自:吉林
等 级:新手上路
帖 子:20
专家分:0
注 册:2016-2-29
得分:0 
回复 4楼 qq1023569223
恩,知道了,谢谢
2016-03-06 17:56



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-462121-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.014841 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved