1. 程式人生 > >洛谷Oj-[USACO1.1]貪婪的送禮者-模擬

洛谷Oj-[USACO1.1]貪婪的送禮者-模擬

問題描述:
對於一群(NP個)要互送禮物的朋友,GY要確定每個人送出的錢比收到的多多少。在這一個問題中,每個人都準備了一些錢來送禮物,而這些錢將會被平均分給那些將收到他的禮物的人。然而,在任何一群朋友中,有些人將送出較多的禮物(可能是因為有較多的朋友),有些人有準備了較多的錢。給出一群朋友,沒有人的名字會長於 14 字元,給出每個人將花在送禮上的錢,和將收到他的禮物的人的列表,請確定每個人收到的比送出的錢多的數目。
AC程式碼:

struct people//人
{
    string name;//名字
    int in;//獲得
    int out;//送出
};
people p[20];
map
<string,int>
m;//注意map<string,people> m;是錯誤的。我們的目的是通過對映,在結構體陣列p中快速找到具有對應姓名的人的編號 int main() { int np;//人數 cin >> np; for(int i = 1; i <= np; ++i) { cin >> p[i].name; m[p[i].name] = i;//對映 } for(int i = 1; i <= np; ++i) { string
t;//姓名 cin >> t; int sum,num;//擁有的錢和送禮的物件數 cin >> sum >> num; if(num == 0)//如果為0 { p[m[t]].out = 0.0;//一分錢都沒送出去 continue; } if(sum % num == 0)//如果能整除 p[m[t]].out = sum; else//不能整除 p[m[t]].out = sum - sum % num;//餘數自己留著
for(int i = 1; i <= num; ++i) { string f;//送禮的物件 cin >> f; p[m[f]].in += sum / num;//收入增加 } } for(int i = 1; i <= np; ++i)//輸出答案 { cout << p[i].name; printf(" %d\n",p[i].in - p[i].out); } return 0; }

解決方法:
題目中雖然要求是平均分配,但是如果無法整除的話,就將剩餘的錢自己留著。
這也是符合實際生活的,沒有誰會送給朋友66.666666元的東西,所以不要使用浮點數
注意除0會導致程式崩潰,一定要對0進行特判
對映在很多題目中是很有用的,map容器的O(lgn)查詢會比線性掃快很多