Problem 77 Greedy Gift Givers

Problem 108一样,Rob简化了这个问题,去掉了BT的测试数据,把问题限定在很小的范围之内,最多10个人,人名不超过14个字母,礼物价值在2000以内,不过这也OK啦,和Problem 108不同,前两个值对整个问题没有什么影响,就算用BT数据,也只是小把戏而已(因为不可能修改人名,弄个长达几十万个字母的名字一点意义都没有,除了增加保存的难度,和算法无关,不是USACO的宗旨,而且要是用cpp,有STL傍身,这种问题根本不会影响到程序)。所以,关注问题本身就可以了,不要太执着于次要的地方。我猜Rob一定收到很多这方面的complaints,嘿嘿

当初这道题目的描述不是很清楚,现在的版本Rob把很多小细节都解释出来了。比如整数除法的问题,我第一次遇到的时候着实郁闷了一下,明明dave给了200收了500,最后怎么会是302。因为每个人的实现会不一样,有的人的代码根本不会遇到这个怎么加减的问题。其实USACO的题目有时候不难,只是编码的时候很多小细节都不要忽视,不然会很不服气。(因为第一次提交就过关和超过一次过关的page会有点不同,虽然我是菜鸟,总归希望能一次过关啦,可要是因为这种非受迫性失误而不能一次过关,心里的感觉真不是窝囊两个字可以形容的@_#)。

本来是用map实现的,简单明了,可惜,map太热心了,它会自动帮你排序,而Rob要求你输出时和输入文件的人名顺序相同。E~~~-_-!其实我想要是换成vector<pair<string,int> >应该也是可以的吧。不过杀鸡焉用牛刀,效率又不比array高,还要多打几行代码,也罢,祭出array大法,直接用数组搞定。唯一比map麻烦的是要自己写一个查人名的函数,不像map可以直接key/value就定位了。

最后,再说一个不是人人遇得到得细节问题(又是detail。。。),其实在它给的样例数据里就有了:vick。这个家伙吝啬的一塌糊涂,只知道拿不知道给。想到什么了没?Yes,他一毛不拔岂不是意味着我在平分礼物的时候要除0!小心啊,同志们。陷阱~~~!那为什么有的人遇不到而我就遇到了呢,看我的代码,我把要分配的平均数事先算出来了,如果忘记check,在运行提交的时候就保准给你一闷棍。要是把这个除法放在后面的for loop里面,就可以避过这个问题了。本意是希望不要做重复劳动,结果好心办坏事 正应了那句"premature optimization is the root of all evil."啊

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int find(string[], string);

int main(){
 int np;
 string* group;
 int*    value;
 
 // get number of members in group
 ifstream fin("gift1.in");
 fin>>np;
 group = new string[np];
 value = new int[np];

 // get members' name
 for(int i = 0;i < np; ++i){
  string name;
  fin>>name;
  group[i] = name;
  value[i] = 0;
 }
 
 // for each member:
 for(int i = 0;i < np; ++i){
  string name;        // this member's name
  int    money,       // money he or she sets aside
         friendnum,   // number of friends is giving gift
         evennum,     // divide money evenly
         mypos;       // this member's position

  fin>>name>>money>>friendnum;
  
  // cheap guy:)
  if(friendnum)
      evennum = money / friendnum;
  
  mypos = find(group, name);
  
  // for every his or her friend:
  for(int j = 0;j < friendnum; ++j){
   string friendname;    // get friend name
   fin>>friendname;
   
   // find friend's position in container
   int frdpos = find(group, friendname);
   
   value[mypos] -= evennum;     // give gift
   value[frdpos] += evennum;    // get gift
  }
 }
 
 ofstream fout("gift1.out");
 for(int i = 0; i < np; ++i){
  fout<<group[i]<<" "<<value[i]<<endl;
 }
}

int find(string group[], string name){
 int i = 0;
 while(group[i] != name) i++;
 return i;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值