USACO Section 1.1 Greedy Gift Givers 解题报告
题目
问题描述
有若干个朋友,朋友之间可以选择互相赠送一些有价值的礼物。一个人可以选择将一部分钱分给若干个朋友,例如某人送给其他两个人钱,总共赠送3元,两个人平均分,原本应该是每人1.5元,但是只能取整数,所以这两个人每人能够得到1元,所以他总共送出去2元,自己剩下1元。
现在,我们知道有NP个人,将NP个人的名字告诉我们,随后给出一个人的名字代表他将进行捐赠,下一行有两个数字,代表这个人的初始的金额X,和要将X元平分给Y个人,下面Y行分别是接受捐赠的人的名字。
最后需要我们计算出,每个人最终的金额与初始金额的差,可能会有负数出现。
数据范围
- 名字不会超过14个字符
2 <= NP <= 100 <= X <= 2000
样例输入
5
dave
laura
owen
vick
amr
dave
200 3
laura
owen
vick
owen
500 1
dave
amr
150 2
vick
owen
laura
0 2
amr
vick
vick
0 0
样例输出
dave 302
laura 66
owen -359
vick 141
amr -150
解题思路
定义一个Person结构体,将姓名、初始金额,和实时金额作为属性保存。之后开始模拟操作即可,在进行除法时请注意避免除数为0的情况。
解题代码
/*
ID: yinzong2
PROG: gift1
LANG: C++11
*/
#define MARK
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
const int maxn = 20;
int num;
struct Person {
char name[maxn];
int iniMoney;
int money;
} p[maxn];
int main() {
#ifdef MARK
freopen("gift1.in", "r", stdin);
freopen("gift1.out", "w", stdout);
#endif
while(~scanf("%d", &num)) {
for(int i = 0; i < num; i++) {
scanf("%s", p[i].name);
p[i].iniMoney = p[i].money = 0;
}
char str1[maxn], str2[maxn];
int ini, cnt;
for(int i = 0; i < num; i++) {
scanf("%s", str1);
scanf("%d%d", &ini, &cnt);
for(int j = 0; j < num; j++) {
if(strcmp(str1, p[j].name) == 0) {
p[j].iniMoney = ini;
p[j].money += ini;
if(cnt != 0)p[j].money -= (ini/cnt)*cnt;
break;
}
}
for(int j = 0; j < cnt; j++) {
scanf("%s", str2);
for(int k = 0; k < num; k++) {
if(strcmp(str2, p[k].name) == 0) {
if(cnt != 0)p[k].money += (ini/cnt);
break;
}
}
}
}
for(int i = 0; i < num; i++) {
printf("%s %d\n", p[i].name, p[i].money-p[i].iniMoney);
}
}
return 0;
}
代码优化
在上一个代码中,每次出现一个人名我必须用循环O(N)的复杂度来查找,确定这个人名是谁之后才能进行操作。现在我用一个map来保存Person的信息,其中名字作为查找的key,对应这个人出现的次序作为value。在代码中我用了一个Person数组p来存储这些人的信息,现在这样用map处理之后,每次得到一个人名,我都能利用p[ map[name] ]这种语句来得到这个人,map查找的时间复杂度为O(logN),如果数据量很大的话这种优化还是挺有效率的。
解题代码(Type 2)
/*
ID: yinzong2
PROG: gift1
LANG: C++11
*/
#define MARK
#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
#include<map>
using namespace std;
const int maxn = 20;
struct Person {
string name;
int iniMoney;
int money;
}p[maxn];
map<string, int> mp;
int np;
int main() {
#ifdef MARK
freopen("gift1.in", "r", stdin);
freopen("gift1.out", "w", stdout);
#endif
while(~scanf("%d", &np)) {
string str;
for(int i = 0; i < np; i++) {
cin >> str;
p[i].name = str;
p[i].iniMoney = p[i].money = 0;
mp[str] = i;
}
int ini, cnt;
for(int i = 0; i < np; i++) {
cin >> str;
scanf("%d%d", &ini, &cnt);
int id = mp[str];
p[id].iniMoney = ini;
p[id].money += ini;
if(cnt != 0) {
p[id].money -= (ini/cnt)*cnt;
}
for(int j = 0; j < cnt; j++) {
cin >> str;
int id2 = mp[str];
if(cnt != 0) {
p[id2].money += (ini/cnt);
}
}
}
for(int i = 0; i < np; i++) {
cout << p[i].name << " " << (p[i].money-p[i].iniMoney) << endl;
}
}
return 0;
}
USACO Section 1.1 Greedy Gift Givers 解题报告的更多相关文章
- USACO Section 1.1-2 Greedy Gift Givers
Greedy Gift Givers 贪婪的送礼者 对于一群(NP个)要互送礼物的朋友,GY要确定每个人送出的钱比收到的多多少. 在这一个问题中,每个人都准备了一些钱来送礼物,而这些钱将会被平均分给那 ...
- Section 1.1 Greedy Gift Givers
Greedy Gift Givers A group of NP (2 ≤ NP ≤ 10) uniquely named friends hasdecided to exchange gifts o ...
- usaco training <1.2 Greedy Gift Givers>
题面 Task 'gift1': Greedy Gift Givers A group of NP (2 ≤ NP ≤ 10) uniquely named friends has decided t ...
- USACO 1.1.2 Greedy Gift Givers(gift1)
这道题大意就是几个人互送礼物,让你求每个人的盈利. 原题给的样例数据: 5(人的个数.) =========(下面是人名,输出按照这顺序)davelauraowenvickamr ========== ...
- USACO Section 1.3 Ski Course Design 解题报告
题目 题目描述 有N座山,每座山都有一个高度,现在由于农夫想避税,所以想把这些山的高度进行一些改变,使得最高的山与最低的山之间的高度差不超过17.每座山最多只能改变一次高度,每次改变高度都会产生一定的 ...
- USACO Section 1.2 Name That Number 解题报告
题目 题目描述 在一个农场里面,每一头牛都有一个数字编号,但是现在这些牛不喜欢这种编号,它们想把这些数字编号转化成为可以接受的字母的形式.数字与字母的转换表如下: 2: A,B,C 5: J,K,L ...
- USACO Section 1.1 Friday the Thirteenth 解题报告
题目 题目描述 黑色星期五是否真的是一件不同寻常的事情?按理来说每个月的13号可能是星期一,或者是星期二...或者是星期天,但是黑色星期五的存在让我们不禁开始猜想,难道每个月的13号刚好是星期五的频率 ...
- USACO Section 1.4 Mother's Milk 解题报告
题目 题目描述 有三个牛奶桶,三个桶的容积分别是A,B,C,最小为1,最大为20.刚开始只有第三个桶里面装满了牛奶,其余两个桶都是空的.我们现在可以将第三个桶中的牛奶往其他两个桶里面倒一些牛奶,然后还 ...
- USACO Training Section 1.1 贪婪的送礼者Greedy Gift Givers
P1201 [USACO1.1]贪婪的送礼者Greedy Gift Givers 题目描述 对于一群(NP个)要互送礼物的朋友,GY要确定每个人送出的钱比收到的多多少.在这一个问题中,每个人都准备了一 ...
随机推荐
- jquery完美实现textarea输入框限制字数
<html> <head> <title> jquery完美实现textarea输入框限制字数</title> <meta http-equiv= ...
- ANT 操控 ORACLE数据库实践
Ant 执行系统命令没有任何问题,这次实际系统命令中可以说遇到了两个问题,一个是启动服务的命令是含有空格的,第二个如何备份数据库可以自动加上日期. 首先,我们启动oracle数据库,操作有两个: 1. ...
- Hibernate 系列教程14-继承-PerTable策略
Employee public class Employee { private Long id; private String name; HourlyEmployee public class H ...
- Segments POJ 3304 直线与线段是否相交
题目大意:给出n条线段,问是否存在一条直线,使得n条线段在直线上的投影有至少一个公共点. 题目思路:如果假设成立,那么作该直线的垂线l,该垂线l与所有线段相交,且交点可为线段中的某两个交点 证明:若有 ...
- POJ 2368 巴什博奕
题目大意:给出n个按钮,每次最多可以按L个,按下最后一个按钮的人获胜.求使后手必定获胜的L的最小值(L>=2). 题目思路: 巴什博弈:只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少 ...
- linux命令-sed,uniq,cut,wc
sort sort 命令对 File 参数指定的文件中的行排序,并将结果写到标准输出.如果 File 参数指定多个文件,那么 sort 命令将这些文件连接起来,并当作一个文件进行排序. sort语法 ...
- 小蚂蚁搬家<贪心>
题意: 由于预知未来可能会下雨,所以小蚂蚁决定搬家.它需要将它的所有物品都搬到新家,新家的体积为V,小蚂蚁有N件物品需要搬,每件物品的体积为Ai,但他发现:每件物品需要新家剩余体积大于等于Bi才能使它 ...
- 深入解析FileInputStream和FileOutputStream
http://swiftlet.net/archives/1363 FileInputStream和FileOutputStream类属于字节类,可以操作任意类型的文件.在数据流的处理过程中,有两种情 ...
- JS-DOM操作应用高级(三)
appendChild 1.先把元素从原有的父级上删除 2.添加到新的父级 <title>无标题文档</title> <script> window.on ...
- JS里的CSS函数
<title>无标题文档</title> <script> function css(obj,name,value){ if(arguments.length==2 ...