和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;
}