3月31:蘑菇街实习笔试:求桌子达最大平衡的代价

Posted RenewDo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了3月31:蘑菇街实习笔试:求桌子达最大平衡的代价相关的知识,希望对你有一定的参考价值。

题目:

   桌子有N 条腿,当桌子不平衡时可以通过砍掉某些来达到最大平衡状态。所谓最大平衡状态是指--桌子最长腿的条数超过桌子的腿总数的一半以上。但桌子的各条腿砍去的代价是不同的,要求达到最大平衡状态时所花的代价最小。

输入:

  6

  2  2  1  1  3  3

  4  3  5  5  2   1

输出:

    8

    下面这种是昨晚自己想法,时间太短没调出来,今天又完善了:

#include <string>
#include <vector>
#include <set>
#include <map>
#include<cctype>
#include<iostream>
#include<string>

using namespace std;
int main()
{
    int n;
    while(cin>>n)
    {
      vector<int> l(n,0);
      vector<int> d(n,0);
      int i=0;
      while(i++<n)
          cin>>l[i-1];
      i=0;
      while(i++<n)
          cin>>d[i-1];
      i=0;
      if(n==1) 
      {
          cout<<0<<endl;
          continue;
      }
      map<int,multiset<int>> res;
      for(int i=0;i<l.size();i++)
      {
          if(res.find(l[i])==res.end())
          {
              multiset<int>tmp;
              tmp.insert(d[i]);
              pair<int,multiset<int>>temp(l[i],tmp);
              res.insert(temp);
          }
          else 
          {
              res[l[i]].insert(d[i]);
          }
      }

      multiset<int>cost;
      map<int,multiset<int>>::iterator res_i=res.begin();
      map<int,multiset<int>>::iterator res_j;
       map<int,multiset<int>>::iterator res_k;
      for(;res_i!=res.end();res_i++)
      {
          int sum=0;   //每次代价总数
          int count=n-(*res_i).second.size();  //每次的应该桌腿总数
          ++res_i;
          for( res_j=res_i;res_j!=res.end();res_j++)//后面长的腿
              {
                  count-=(*res_j).second.size();
                  for(multiset<int>::iterator m=(*res_j).second.begin();m!=(*res_j).second.end();m++)
                  {
                      sum+=*m;
                  }
              }
          res_i--;
          if((*res_i).second.size()>count)
          {
              cost.insert(sum);
               continue;
          }
          else{
              multiset<int> before_d;
              for(res_k=res.begin();res_k!=res_i;res_k++)
              {
                  for(multiset<int>::iterator m=(*res_k).second.begin();m!=(*res_k).second.end();m++)
                  {
                      before_d.insert(*m);
                  }
              }

            multiset<int>::iterator it=before_d.begin();
            for(count;count>(*res_i).second.size()-1;count--,it++)
            {
                sum+=*it;
            }
            cost.insert(sum);
          }
      }
      cout<<*(cost.begin())<<endl;
    }
    return 0;
}

上面是利用map实现两个元素排列的。

 

 

下面这种是利用定义类进行封装,还要进行重载函数:

#include <string>
#include <vector>
#include <set>
#include <map>
#include<cctype>
#include<iostream>
#include<string>
#include<algorithm>

using namespace std;
class Leg
{
public:
    int length;
    int cost;
    Leg(int x,int y):length(x),cost(y){}
    bool operator < (const Leg& a) const //不加const会报错的
    {
       return length<a.length;
    }
    bool operator=(const Leg& a)const
    {
        return length==a.length;
    }
};
class Leg_cost
{
public:
    int length;
    int cost;
    Leg_cost(int x,int y):length(x),cost(y){}
    bool operator <(const Leg_cost& a) const
    {
       return cost<a.cost;
    }
};
int main()
{
    int n;
    while(cin>>n)
    {        
        multiset<Leg> res;
        set<int>len;
        vector<int>l(n,0);
        int i=0;
        while(i++ < n)
        {
            cin>>l[i-1];
            len.insert(l[i-1]);
        }
        i=0;
        while(i++ < n)
        {
            int tmp;
            cin>>tmp;
            res.insert(Leg(l[i-1],tmp));
        }
        pair<multiset<Leg>::iterator ,multiset<Leg>::iterator>max;
        multiset<int>min_cost;
        for(set<int>::iterator cur=len.begin();cur!=len.end();cur++)
        {
            int count=n-res.count(Leg(*cur,0));
            int sum=0;
            max=res.equal_range(Leg(*cur,0));  //[)之前定义<时,还比较了cost,后来发现equal_range的内部实现函数用的是<,所以取消了cost比较

            for(multiset<Leg>::iterator after=max.second;after!=res.end();after++)
            {
                sum+=after->cost;
                count--;
            }
            if(res.count(Leg(*cur,0))>count)
            {
                min_cost.insert(sum);
                continue;
            }
            else
            {
                multiset<Leg_cost>del_cost;
                multiset<Leg_cost>::iterator it;
                for(multiset<Leg>::iterator before=res.begin();before!=max.first;before++)
                {                    
                    del_cost.insert(Leg_cost(before->length,before->cost));
                }
                for(it=del_cost.begin();count>res.count(Leg(*cur,0))-1;count--)
                {
                    sum+=it->cost;
                }
                min_cost.insert(sum);
            }

        }
        cout<<*(min_cost.begin())<<endl;
    }
    return 0;
}

 

以上是关于3月31:蘑菇街实习笔试:求桌子达最大平衡的代价的主要内容,如果未能解决你的问题,请参考以下文章

写给立志做码农的大学生(蘑菇街你都挂了,你还要面腾讯? 我去,我一定要去)

方格走法 蘑菇街笔试题

2016蘑菇街编程题:最大间隔

美丽说与蘑菇街都有哪些区别

双非菜鸟的Java实习面试经历..

蘑菇街已连续亏损3年,技术部门裁员80%,为何会陷入至此境地?