zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    启动matlab时总是直接跳转到安装界面的解决方案
    毕业倒计时
    PARAMETER和ARGUMENT的区别
    在Windows上使用Ubuntu共享的打印机
    Ubuntu 16.04 + CUDA 8.0 + cuDNN v5.1 + TensorFlow(GPU support)安装配置详解
    深度学习硬件购买指南
    GeForce GTX 1080 ti安装记录
    What is a TensorFlow Session?
    来来来,干了这碗毒鸡汤……
    [译] 理解 LSTM(Long Short-Term Memory, LSTM) 网络
  • 原文地址:https://www.cnblogs.com/daocaorenblog/p/5346546.html
Copyright © 2011-2022 走看看