程序设计:座位调整

原创 2006年05月28日 22:25:00

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;
}

相关文章推荐

2006 年百度之星程序设计大赛初赛题目---座位调整--菜鸟学习算法

座位调整 2006 年百度之星程序设计大赛初赛题目 5  座位调整  题目描述:  百度办公区里到处摆放着各种各样的零食。百度人力资源部的调研发现,员工如果可以在自己喜欢的美食...

php:百度Astar2006程序设计大赛预赛题--座位调整

5.座位调整 百度办公区里到处摆放着各种各样的零食。百度人力资源部的调研发现,员工如果可以在自己喜欢的美食旁边工作,效率会大大提高。因此,百度决定进行一次员工座位的大调整。调整的方法如下:1.首先将办...
  • wxhlxx
  • wxhlxx
  • 2011年05月31日 20:54
  • 662

2006年百度之星程序设计大赛试题初赛题目-题5-座位调整

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

L1-005. 考试座位号-PAT团体程序设计天梯赛GPLT

L1-005. 考试座位号 每个PAT考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位。正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试...
  • liuchuo
  • liuchuo
  • 2016年09月09日 16:54
  • 461

团体程序设计天梯赛-练习集 L2-010. 排座位

L2-010. 排座位 时间限制 150 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 ...

2016年团体程序设计天梯赛-初赛 - 排座位(并查集)

布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位。无论如何,总不能把两个死对头排到同一张宴会桌旁!这个艰巨任务现在就交给你,对任何一对客人,请编写程序告诉主人他们是否能被安排同席。 输入格...

L2-010. 排座位-PAT团体程序设计天梯赛GPLT(并查集)

L2-010. 排座位 布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位。无论如何,总不能把两个死对头排到同一张宴会桌旁!这个艰巨任务现在就交给你,对任何一对客人,请编写程序告诉主人他们是否能...
  • liuchuo
  • liuchuo
  • 2016年08月12日 20:50
  • 355

团体程序设计天梯赛-练习集 L2-010. 排座位 解题报告

L2-010. 排座位 时间限制 150 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 ...

团体程序设计天梯赛——排座位(dfs)

布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位。无论如何,总不能把两个死对头排到同一张宴会桌旁!这个艰巨任务现在就交给你,对任何一对客人,请编写程序告诉主人他们是否能被安排同席。输入格式:输入...

VB抽奖程序(按座位抽奖)

  • 2008年01月08日 22:46
  • 6.87MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:程序设计:座位调整
举报原因:
原因补充:

(最多只允许输入30个字)