座位调整

题目描述: 

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

调整的方法如下: 

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

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

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

数据输入: 

第一行包含两个整数 N , M ,( 1<=N , 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 



输出样例


175 




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

代码为:
#include<stdio.h>

int main()
{
    int m,n,sum=0,s;
    printf("请输入区域数和人数:\n");
    scanf("%d",&n);
    scanf("%d",&m);
    int a[100],b[100][100];
    printf("输入各个区域的容纳人数:\n");
    int i,j;
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    printf("输入每个人对各区域的喜好度:\n");
    for(i=0;i<m;i++)
        for(j=0;j<n;j++)
            scanf("%d",&b[i][j]);
    s=m;
    while(s)
    {
        int max=0,h,l;
        for(i=0;i<m;i++)
            for(j=0;j<n;j++)
                if(b[i][j]>max)
                {
                    max=b[i][j];
                    h=i;
                    l=j;
                }
        --a[l];
        if(a[l]==0)
        {
            for(i=0;i<m;i++)
                b[i][l]=0;
        }
        for(j=0;j<n;j++)
            b[h][j]=0;
        sum=sum+max;
        --s;
    }
    printf("最大喜好度是:%d\n",sum);
    return 0;
}

1.#include<iostream>
using namespace std;
void main()
{   int N,M,i,j;
    cin>>N>>M;
    int cap[300];
    for (i=0;i<N;i++)
    {
        cin>>cap[i];
    }int favour[90000];
    for (j=0;j<M*N;j++)
    {
        cin>>favour[j];
    }
    

    int areanum,k,h,sum=0,max,runtime=M;
    while(runtime>0)
    {
        max=-1;
        for (j=0;j<M*N;j++)
        {
            if(favour[j]>=max)
            {
                max=favour[j];
                k=j;
            }
        }
        areanum=k%N;
        if(cap[areanum]>0)
        {
            cap[areanum]--;
            sum=sum+max;
            for(h=k-areanum;h<=k-areanum+N-1;h++)
            {
                favour[h]=-1;
            }
            runtime--;
        }
        if(cap[areanum]==0)
        {
            for(int a=0;a<N;a++)
            {
                favour[areanum+a*M]=-1;
            }
        }


    }


    cout<<"the result is:"<<" "<<sum;
    
    system("pause");
}

2.#include<stdio.h>
int max(int* a,int n) //求一整型数组最大值
{
int max=0,i; 
for(i=0;i<n;i++) 
{
if(a[i]>max) 
max=a[i];
} 
return max;
}
int sort1(int* a,int n)//对一个整型数组冒泡排序
{ 
int i,j,k;
for(j=0;j<n-1;j++) 
for(i=0;i<n-1-j;i++)
{if(a[i]<a[i+1]) 
{ 
k=a[i]; 
a[i]=a[i+1]; 
a[i+1]=k; 
} 
}
}
int sort(int n,int m,int a[n],int p[m][n])//座位分配函数
{ 
int b[n][m]={}; 
int c[m][n]; 
int sum[n]={}; 
int i,j,count=0; 
for(i=0;i<m;i++)
for(j=0;j<n;j++) 
{
c[i][j]=p[i][j];
}
for(j=0;j<n;j++) 
{ 
for(i=0;i<m;i++)
{ 
if(p[i][j]==max(&c[i][0]),j)
{ 
b[j][count]=p[i][j];
count++; 
} 
} 
if(count<=a[j])
{ 
for(i=0;i<count;i++) 
{ 
sum[j]+=b[j][i]; 
} 
} 
else 
{ 
sort1(*b[j][0],m);
for(i=0;i<a[j];i++) 
sum[j]+=b[j][i]; 
} 
} 
}
int main()
{
int Sum=0; 
int sort(int n,int m,int a[n],int p[m][n]);
for(i=0;i<n;i++)
Sum+=sum[i]; 
return Sum;
printf("Sum:%d",Sum);
}


3.#include <stdio.h>
void main()
{
	int a[100],n,m,i,j,g=0;
	int b[10][10];
	scanf("%d%d",&n,&m);
	for(i=0;i<n;i++)
		scanf("%d",&a[i]);
	for(i=0;i<n;i++)
		for(j=0;j<m;j++)
			scanf("%d",&b[i][j]);
	for(i=0;i<n;i++)
		g+=b[0][i];
	printf("\n%d\n",g);
}

4.//head.h
void accommodate(int *(&a),int N,int M);//实现容纳数组的赋值
void love(int**(&L),int,int);//实现喜好程序M*N的矩阵的输入;
long anneal(int**,bool**,int N,int M);//退火算法得出最大的喜好程度
bool** initia(int *a,int N,int M);//退火算法的0-1初始化矩阵

//函数实现.cpp

#include <iostream>
#include <malloc.h>
#include <iomanip>
#include <time.h>
using namespace std;
void accommodate(int *(&a),int N,int M){//实现容纳数组的赋值;
    int i,m=0;//m为当前容纳数组的和
    a=(int*)malloc(N*sizeof(int));
    if(a==NULL){
        cout<<"第一次内存分配失败,进行第二次内存分配"<<endl;
        a=(int*)malloc(N*sizeof(int));
    }
    cout<<"请输入每个区域中的工作人员数并且之和为"<<M<<
        ",如果不等于,系统会提示重新输入"<<endl;
    for(i=0;i<N;i++)
        *(a+i)=0;//为容纳数组赋初值
    for(i=0;i<N;i++){
        cin>>*(a+i);
        if((m+=*(a+i))>M){
            cout<<"您当前的输入已经大于了员工总人数"<<M<<"请重新输入"<<endl;
            i=0;
            continue;
        }
        if(i==N-1 && m<M){
            cout<<"您当前的输入小于员工总人数"<<M<<"请重新输入"<<endl;
            i=0;
            continue;
        }
    }
}

void love(int **(&l),int N,int M){//实现喜好程序M*N的矩阵的输入;
    int i,j;
    l=(int**)malloc(M*sizeof(int*));
    for(i=0;i<M;i++)
        *(l+i)=(int*)malloc(N*sizeof(int));
    cout<<"请输入"<<M<<"*"<<N<<"的喜好程序矩阵每个元素"<<
        "的范围为0~100如有一个不在该区间则重新输入"<<endl;

    for(i=0;i<M;i++)
        for(j=0;j<N;j++){
            cin>>*(*(l+i)+j);
            if(*(*(l+i)+j)<0 || *(*(l+i)+j)>100){
                j=N;i=-1;
            cout<<"您输入的数据不在0~100内故请重新输入"<<endl;
            }
        }
    cout<<"您输入的喜好程度矩阵为"<<endl;
    for(i=0;i<M;i++){
        for(j=0;j<N;j++)
            cout<<setw(5)<<*(*(l+i)+j);
        cout<<endl;
    }
}

bool **initia(int *a,int N,int M){//退火算法的0-1初始化矩阵,a是岗位员工数组
    bool **init;
    int i,j,k=0;
    init=(bool**)malloc(M*sizeof(bool*));
    for(i=0;i<M;i++)
        *(init+i)=(bool*)malloc(N*sizeof(bool));
    for(i=0;i<M;i++)
        for(j=0;j<N;j++)
            *(*(init+i)+j)=0;
    i=0;
    for(j=0;j<N;j++){
        for(i;i<(*(a+j)+k);i++)
            *(*(init+i)+j)=1;
        k+=*(a+j);
    }
    return init;
}

long anneal(int **l,bool **init,int N,int M){//退火算法得出最大的喜好程度
    //l为喜好程度矩阵,a为容纳员工数数组;
    //初始化0-1矩阵,每行=1,第i列的和为a[i]
    int i,j,r1,r2;//做交换的两行其值不能相等
    long max=0,tmp,count=0;
    for(i=0;i<M;i++)
        for(j=0;j<N;j++)
            if(*(*(init+i)+j)==1)
                max+=*(*(l+i)+j);//初始化时的喜好程度
    srand(time(0));
    while(count<10000){
    do{
    r1=rand()%M;r2=rand()%M;
    }while(r1==r2);
    for(j=0;j<N;j++){
        if(init[r1][j]==1 && init[r2][j]==0){
            init[r1][j]=0;init[r2][j]=1;
        }
        else if(init[r1][j]==0 && init[r2][j]==1){
            init[r1][j]=1;init[r2][j]=0;
        }
    }
    tmp=0;
    for(i=0;i<M;i++)
        for(j=0;j<N;j++)
            if(*(*(init+i)+j)==1)
                tmp+=*(*(l+i)+j);
    if(tmp<max)
    for(j=0;j<N;j++){
        if(init[r1][j]==1 && init[r2][j]==0){
            init[r1][j]=0;init[r2][j]=1;
        }
        else if(init[r1][j]==0 && init[r2][j]==1){
            init[r1][j]=1;init[r2][j]=0;
        }
    }
    else{
        max=tmp;count++;
    }
    }
    cout<<"\n所得结果的0-1矩阵为"<<endl;
    for(i=0;i<M;i++){
        for(j=0;j<N;j++)
            cout<<setw(4)<<*(*(init+i)+j);
        cout<<endl;
    }
    return max;
}

//main.cpp
//本题给我的第一感觉是运用退火算法去解决
#include <iostream>
#include <malloc.h>
#include <iomanip>
using namespace std;
int main(){
    int N,M,*a=NULL,**L=NULL;//喜好度矩阵
    bool **ini=NULL;//位置0-1矩阵
    long max;//最大满意度
    //N为区域数,M为员工数,a为每个区域的员工数,长度为N,其和为M
    cout<<"请输入区域数及公司的员工数 :"<<endl;
    cin>>N >>M;
    accommodate(a,N,M);
    love(L,N,M);
    ini=initia(a,N,M);
    max=anneal(L,ini,N,M);
    cout<<"最大值为: "<<max<<endl;
    return 0;
}

5.
#include <stdio.h>
void sort(int a[],int b[])//b函数得到a函数大小排序的下标值
{

   int i,j,max,t;//b保存下标
   int length=sizeof(a);
   for(i=0;i<length-1;i++)
   {
      max=-1;
      t=0;
      for(j=0;j<length-1;j++)
      {
         if(i==0)
         { 
             if(a[j]>max)
             {
                max=a[j];
                t=j;
             }
         }else {
             if(a[j]>max&&a[j]<a[b[i-1]])
             { 
                 max=a[j];
                 t=j;
             }
         }
      }
      b[i]=t;
   }
}
void main()
{
   int i,m,n,a[100],b[100],c[100],j,total;
   scanf("%d%d",&n,&m);//n代表区 m代表人
   for(i=0;i<n;i++)
   {
        scanf("%d",&a[i]);//获得每个区的人数
   }
   total=0;
      for(i=0;i<m;i++)
      {
           for(j=0;j<n;j++)
              {
                  scanf("%d",&b[j]);
              }
              sort(b,c);
           for(j=0;j<n;j++) //获取某人属于哪个区
           {
               if(a[c[j]]!=0)
               {
                   a[c[j]]--;
                   printf("______%d\n",b[c[j]]);
                   total+=b[c[j]];
                   break;
               }
           }
      }
      printf("%d",total);
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值