程序设计:座位调整

5.座位调整

百度办公区里到处摆放着各种各样的零食。百度人力资源部的调研发现,员工如果可以在自己喜欢的美食旁边工作,效率会大大提高。因此,百度决定进行一次员工座位的大调整。

调整的方法如下:

1.首先将办公区按照各种零食的摆放分成N个不同的区域(例如:可乐区,饼干区,牛奶区等等);

2.每个员工对不同的零食区域有不同的喜好程度(喜好程度是1~100的整数, 喜好程度越大表示该员工越希望被调整到相应的零食区域);

3.由于每个零食区域可以容纳的员工数量有限,人力资源部希望找到一个最优的调整方案使得总的喜好程度最大。

输入要求:

文件第一行包含两个整数N,M(N>=1,M<=300)。分别表示N个区域和M个员工;

第二行是N个整数构成的数列a,其中a[i]表示第i个区域可以容纳的员工数(1<=a[i]<=M,a[1]+a[2]+...+a[N]=M);

紧接着是一个M*N的矩阵P,P(i,j)表示第i个员工对第j个区域的喜好程度。例:

3 3

1 1 1

100 50 25

100 50 25

100 50 25

样例:in.txt

输出要求:

对于每个测试数据,输出可以达到的最大的喜好程度。例:

175

样例:out.txt

数据解释:

此数据只存在一种安排方法,三个员工分别安置在三个区域。最终的喜好程度为100+50+25=175

评分规则:

1.程序将运行在一台Linux机器上(内存使用不作严格限制),在每一测试用例上运行不能超过10秒,否则该用例不得分;

2.要求程序能按照输入样例的格式读取数据文件,按照输出样例的格式将运行结果输出到标准输出上。如果不能正确读入数据和输出数据,该题将不得分;

3.该题目共有4个测试用例,每个测试用例为一个输入文件。各测试用例占该题目分数的比例分别为25%,25%,25%,25%;

4.该题目20分。

解答:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>

#define MENU_NAME_LEN 42

#define Q5_TRUE 1
#define Q5_FALSE 0

#define Q5_UNUSED_ITEM 600

long g_arrReference[300];     /* [lM] */
long g_arrPeople[300][300];   /* [lM][lN] */

long g_arrPermitted[300];     /* [lN] */
long g_arrAreaList[300][300]; /* [lN][lM] */
long g_arrSolution[300][300]; /* [lN][lM] */

long g_arrDupList[300][301];  /* [lM][1 + lDupCnt] */

long g_lCntSort;

char * ReadInt(char * sz, long * out)
{
    long i;
    long lPos;
    char szBuf[100];

    for (i = 0; ' ' == sz[i]; i++)
    {
        /* nothing */
    }

    lPos = i;

    for (; sz[i] && ' ' != sz[i]; i++)
    {
        /* nothing */
    }

    strncpy(szBuf, sz + lPos, i - lPos);
    szBuf[i - lPos] = '/0';
    *out = atol(szBuf);

    return sz + i;
}

long compare( const void *arg1, const void *arg2)
{
    return g_arrPeople[*(long*)arg1][g_lCntSort] < g_arrPeople[*(long*)arg2][g_lCntSort];
}

long GetTotal(long lN, long lM)
{
    long lTotal = 0;
    long i, j;

    for (i = 0; i < lN; i++)
    {
        for (j = 0; j < g_arrPermitted[i]; j++)
        {
            lTotal += g_arrPeople[g_arrAreaList[i][j]][i];
        }
    }

    return lTotal;
}

long GetSwapResult(long lN, long lM, long lKey)
{
    long i, j;
    long lMaxCost = -1;
    long lCost = 0;
    long lMaxTotal = 0;
    long lIndex = 0;
    long lPermitted;
    long arrKeyToSwap[300][2]; /* [lN] */
    long lTemp;
    long lDupCnt = 0;
    long lOldCnt;
    char bDecided = Q5_FALSE;

    for (i = 0; i < g_arrDupList[lKey][0]; i++)
    {
        lPermitted = g_arrPermitted[g_arrDupList[lKey][i + 1]];

        for (j = 0; j < lPermitted; j++)
        {
            if (g_arrAreaList[g_arrDupList[lKey][i + 1]][j] == lKey)
            {
                break;
            }
        }

        arrKeyToSwap[g_arrDupList[lKey][i + 1]][0] = j;

        do
        {
            lCost = g_arrPeople[lKey][g_arrDupList[lKey][i + 1]]
                  - g_arrPeople[g_arrAreaList[g_arrDupList[lKey][i + 1]][lPermitted]][g_arrDupList[lKey][i + 1]];
            lPermitted++;
        } while (lCost < 0);

        arrKeyToSwap[g_arrDupList[lKey][i + 1]][1] = lPermitted - 1;

        if (lCost > lMaxCost)
        {
            lMaxCost = lCost;
            lIndex = i;
        }
    }

    if (!lMaxCost)
    {
        for (i = 0; i < g_arrDupList[lKey][0]; i++)
        {
            if (g_arrDupList[g_arrAreaList[ g_arrDupList[lKey][i + 1] ][ arrKeyToSwap[g_arrDupList[lKey][i + 1]][1] ] ][0] > 1)
            {
                lIndex = i;
                bDecided = Q5_TRUE;
                break;
            }
        }
    }

    if (!bDecided)
    {
        for (i = 0; i < g_arrDupList[lKey][0]; i++)
        {
            lPermitted = arrKeyToSwap[g_arrDupList[lKey][i + 1]][1];

            do
            {
                lPermitted++;
                lCost = g_arrPeople[lKey][g_arrDupList[lKey][i + 1]]
                    - g_arrPeople[g_arrAreaList[g_arrDupList[lKey][i + 1]][lPermitted]][g_arrDupList[lKey][i + 1]];
            } while ((lCost < 0
                || g_arrDupList[g_arrAreaList[ g_arrDupList[lKey][i + 1] ][ lPermitted ] ][0])
                && lPermitted < lM);

            if (lPermitted != lM)
            {
                arrKeyToSwap[g_arrDupList[lKey][i + 1]][1] = lPermitted;
            }
            else
            {
                lIndex = i;
            }
        }
    }

    for (i = 0; i < g_arrDupList[lKey][0]; i++)
    {
        if (i != lIndex)
        {
            lTemp = g_arrAreaList[ g_arrDupList[lKey][i + 1] ][ arrKeyToSwap[ g_arrDupList[lKey][i + 1] ][1] ];
            g_arrAreaList[ g_arrDupList[lKey][i + 1] ][ arrKeyToSwap[ g_arrDupList[lKey][i + 1] ][1] ] =
                g_arrAreaList[ g_arrDupList[lKey][i + 1] ][ arrKeyToSwap[ g_arrDupList[lKey][i + 1] ][0] ];
            g_arrAreaList[ g_arrDupList[lKey][i + 1] ][ arrKeyToSwap[ g_arrDupList[lKey][i + 1] ][0] ] = lTemp;

            g_arrDupList[lTemp][0]++;
            g_arrDupList[lTemp][g_arrDupList[lTemp][0]] = g_arrDupList[lKey][i + 1];
        }
    }

    lOldCnt = g_arrDupList[lKey][0];
    g_arrDupList[lKey][0] = 1;

    for (i = 0; i < lM; i++)
    {
        if (g_arrDupList[i][0] > 1)
        {
            lDupCnt++;
            lTemp = GetSwapResult(lN, lM, i);

            if (lTemp > lMaxTotal)
            {
                lMaxTotal = lTemp;
            }
        }
    }

    if (!lDupCnt)
    {
        lMaxTotal = GetTotal(lN, lM);
    }

    g_arrDupList[lKey][0] = lOldCnt;

    for (i = 0; i < g_arrDupList[lKey][0]; i++)
    {
        if (i != lIndex)
        {
            lTemp = g_arrAreaList[ g_arrDupList[lKey][i + 1] ][ arrKeyToSwap[ g_arrDupList[lKey][i + 1] ][0] ];
            g_arrAreaList[ g_arrDupList[lKey][i + 1] ][ arrKeyToSwap[ g_arrDupList[lKey][i + 1] ][0] ] =
                g_arrAreaList[ g_arrDupList[lKey][i + 1] ][ arrKeyToSwap[ g_arrDupList[lKey][i + 1] ][1] ];
            g_arrAreaList[ g_arrDupList[lKey][i + 1] ][ arrKeyToSwap[ g_arrDupList[lKey][i + 1] ][1] ] = lTemp;

            g_arrDupList[lTemp][0]--;
        }
    }

    return lMaxTotal;
}

/*
  lN is Area count
  lM is People count
 */
long GetBestSolution(long lN, long lM)
{
    long i, j;
    long lDupCnt = 0;
    long lTotal = 0;
    long lMaxTotal = 0;

    if (1 == lN)
    {
        for (i = 0; i < lM; i++)
        {
            lTotal += g_arrPeople[i][0];
        }

        return lTotal;
    }

    for (i = 0; i < lN; i++)
    {
        for (j = 0; j < g_arrPermitted[i]; j++)
        {
            g_arrDupList[g_arrAreaList[i][j]][0]++;
            g_arrDupList[g_arrAreaList[i][j]][g_arrDupList[g_arrAreaList[i][j]][0]] = i;
        }
    }

    for (i = 0; i < lM; i++)
    {
        if (g_arrDupList[i][0] > 1)
        {
            lDupCnt++;
            lTotal = GetSwapResult(lN, lM, i);

            if (lTotal > lMaxTotal)
            {
                lMaxTotal = lTotal;
            }
        }
    }

    if (!lDupCnt)
    {
        return GetTotal(lN, lM);
    }

    return lMaxTotal;
}

long main(long argc, char* argv[])
{
    FILE * fp = fopen(argv[1], "r");
    char szBuf[4096], *pBuf;
    long lN, lM;
    long i, j;
    long lRet;

    fgets(szBuf, 4096, fp);
    pBuf = ReadInt(szBuf, &lN);
    pBuf = ReadInt(szBuf, &lM);

    fgets(szBuf, 4096, fp);
    pBuf = szBuf;

    for (i = 0; i < lN; i++)
    {
        pBuf = ReadInt(pBuf, &g_arrPermitted[i]);
    }

    for (i = 0; i < lM; i++)
    {
        fgets(szBuf, 4096, fp);
        pBuf = szBuf;

        for (j = 0; j < lN; j++)
        {
            g_arrAreaList[j][i] = i;
            pBuf = ReadInt(pBuf, &g_arrPeople[i][j]);
        }
    }

    for (g_lCntSort = 0; g_lCntSort < lN; g_lCntSort++)
    {
        qsort(g_arrAreaList[g_lCntSort], lM, sizeof(long), compare);
    }

    fclose(fp);

    /* algorithm */
    lRet = GetBestSolution(lN, lM);
    printf("%ld", lRet);

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值