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;
}
时间: 2024-08-10 00:05:37

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

java中求一下2008年5月31日, 往前倒30天是哪天?

题目9: 2008年5月31日, 往前倒30天是哪天? (视频下载) (全部书籍)本章源码import java.util.*;public class Test {    public static void main(String[] args) {        Date date;        Calendar cal = Calendar.getInstance();        cal.set(Calendar.YEAR, 2008);        cal.set(Calend

2015腾讯暑期实习笔试题目

2015腾讯暑期实习笔试题目 (1).层次遍历序列为ABCDEFG的二叉树,其中序遍历的序列是什么? (2).ABCABC为入栈的顺序,倘若出栈的顺序为ABCCBA,那么,设栈的操作为PUSH和POP,则PUSH和POP的可能序列是什么? (3).使用顺序数组存储堆,90,31,53,23,16,48:16,31,23,90,53,48:这两个序列是否符合堆的定义. (4).稀疏矩阵的存储结构可以是什么? (5).根据后序遍历和中序遍历的序列,如何恢复此二叉树. (6).Linux常用命令:ls

5月31日上午学习日志

5月31日上午写了一套四级真题并纠错改正总结,复习了一部分之前背的考研词汇,听外教的java课程,用扇贝app完成英语100个四级单词的记忆.

7月31号=》311页-315页

13.6.1 语句块 所谓语句块就是使用花括号包含的多个语句,语句块是一个整体的执行体,类似于一个单独的语句. 代码示范: { a = 1; b = 2; alert(a+b); } 13.6.2 空语句 最简单的空语句仅有一个分号(;) 代码示范: //空语句 ; //使用空语句完成数组的初始化 var a = []; for(var i = 0;i<10;a[i++] = i+20); 13.6.3 异常抛出语句 JavaScript支持异常处理,支持手动抛出异常.当JavaScript需要

2017年3月31日下午学习日志

2017年3月31下午复习了高等数学,继续看了张宇高等数学基础班课程视频第二章导数与微分不定积分的概念12,第二遍听课过程中能巩固之前所学内容,不懂的问题得以解决,印象也更加深刻,对复习有很大的帮助,背英语单词100个.

2014年5月31日 《失控 第一章 人造与天生》读后感

从今天开始,每读完<失控>的一章,我都要写下我的读后感,可能是摘要,也获许是我自己的看法和感悟.坚持下去! 接下来是第一章   人造与天生. 人造与天生的联姻是本书的主题. 在我看来,如果世界被分成两部分,那么一部分就是自然世界,另一部分就是人造世界.它们并不是相对的,而是共存的,相互依赖,相互成长的(但是我认为人造世界更加依赖自然世界,因为人造世界就是在自然世界的基础上构建的).自然世界,赠与了人们一切最基础的生存来源,是一个强大的生物基因库,如果你认为它只是给人们提供了这些,那就错了,更重

coding!8月31日 来挖文兑现承诺

价值为导向,效率为王. 一个不反思自己带给别人什么价值的人,永远不可能赚到钱,谁愿意和这样的人合作呢. 所以我要让自己变得很贵很值钱. 学习不可以再断断续续,要每天坚持,雷打不动,就像我减肥时一样,没有这样的决心,一个人永远不可能成功.如果有干扰你的东西,想办法消除它,我要有自己的原则.原则是任何事情都不能触碰的我的底线,也是用生命都要捍卫的东西.因为我知道如果没有原则,我会活的连狗都不如.反之,如果我恪守我的原则,即使现在失去一些东西,将来我必然能得到更好的. 我必须全力以赴,但是不能只盯着书

2017年10月31日结束Outlook 2007与Office 365的连接

2017 年10月31日 ,微软即将推出 Office 365中Exchange Online邮箱将需要Outlook for Windows的连接,即通过HTTP Over MAPI方式,传统使用RPC over HTTP(例如Outlook 2007)的Windows客户端的Outlook将无法访问Exchange Online邮箱,不再支持. RPC over HTTP协议,也称为Outlook Anywhere,是Windows OS系统 Outlook客户端和Exchange 服务器之

2015微软创新杯Imaginecup大赛报名进行中(报名截止2014年12月31日23:59)

CSDN高校俱乐部与微软官方合作,2015微软创新杯大赛中国区官网落户CSDN高校俱乐部:http://student.csdn.net/mcs/imaginecup2015 在微软官方设置创新杯中国区奖项之外,CSDN高校俱乐部每个竞赛项目特设一等奖.二等奖.三等奖及纪念奖若干名. CSDN高校俱乐部特别奖(获奖者需在高校俱乐部进行过报名备案):详情-> 1. 一等奖(三支团队): 每个竞赛项目一等奖一名,每支团队获得奖金2,000元人民币,团队成员每人尊享2015 CSDN VIP年卡会员: