您的位置:首页 > 其它

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

2016-04-01 22:03 369 查看
题目:

桌子有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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: