USACO Section 1.1 Greedy Gift Givers

来源:互联网 发布:锐捷客户端for mac 编辑:程序博客网 时间:2024/05/16 18:18

题目描述

一组NP(2≤NP≤10)唯一命名的朋友决定交换礼物。这些朋友中的每一个都可能或不可能给任何或所有其他朋友一些钱。同样,每个朋友也许或可能不会从任何一个或所有其他朋友那里收到钱。你在这个问题上的目标是推断出每个人给予的钱比他们收到多少钱。赠送礼物的规则可能与您预期的不同。每个人放弃一定数量的钱,将这笔钱均匀分配给他或者正在给予礼物的所有人中。没有分数的钱可用,所以在2个朋友中,除了3个,对于剩下1个的朋友,每个1个,剩下1个留在提交者的“帐户”中。在任何一群朋友中,有些人比别人更多(或者至少可能有更多的熟人),有些人比其他人有更多的钱。给予一群朋友,其中没有一个姓名长度超过14个字符,团体中的每个人花费的礼物和每个人给予礼物的(子)列表的朋友,确定多少(或较少)组中每个人给予的比他们收到。

重要提示

分级机是使用标准Unix约定的Linux机器:行尾是通常被称为“\ n”的单个字符。 这不同于Windows,它结束了两个字符'\ n'和'\ r'的行。 不要让你的程序被这个困住!

程序名称:gift1

输入格式

第1行:单个整数,NP
行2..NP + 1:每行包含组成员的名称
线NP + 2..end:NP组的线组织如下:
小组的第一行告诉该人的名字将会赠送礼物。
该组的第二行包含两个数字:起始金额(在0..2000范围内)由提供者分配为礼物,然后送达送礼者的人数NGi(0 ≤NGi≤NP-1)。
如果NGi不是零,则下一个NGi行列出了礼物收件人的姓名。

输入 (file gift1.in)
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

输出格式

输出是NP行,每个都有一个人的名字,后面跟着一个空白,然后是该人的净收益或损失(final_money_value - initial_money_value)。 这些名称应该按照输入的第2行开始的顺序打印。
所有的礼物都是整数。 每个人给予给予任何钱的每个朋友相同的整数金额,并尽可能多地符合这个约束。 任何没有给予的钱都由提供者保存。

输出 (file gift1.out)

dave 302
laura 66
owen -359
vick 141
amr -150

输出说明

五个名字:dave,laura,owen,vick,amr让我们保留每个人的“给”(钱)的表:

davelauraowenvickamr00000

第一,'dave'把自己的200元平均分给'laura','owen'和'vick'三人。 则每人66元,剩下2元在'dave'手中:

-200+26666660

第二,'owen'给了'dave'500元:

-198+5006666-500660

第三,'amr'把自己的150元平均给了'vick','owen':

30266-434+7566+75-150

第四,'laura'把自己的0元平均给了'amr' and 'vick';无改变:

30266-359141-150

第五,'vick’把0元给了无人:

davelauraowenvickamr30266-359141-150

解题思路

本题主要思路是,输入了很多行(其中包括固定的数据和对固定数据进行处理的数据),我们需要把固定的数据提取出来存放在静态数组中,然后再把对固定数据进行处理的数据提取出来,对动态数组进行处理(其中最重要的一步就是判断每个人的名字存在静态数组的第几个,下面用了两种方式1,定义了一个函数用来判断它在第几个。2,直接用map来存储直接展现了人名字和钱之间的对应关系)。

解题代码

1,定义一个函数

/*ID: 15189822PROG: gift1LANG: C++*/#include<iostream>#include<cstring>#include<fstream>using namespace std;ifstream fin("gift1.in");//输入文件流 ofstream fout("gift1.out");//输出文件流 const int N = 10;char s[N+1][2*N+1];//最多10人,且每个人的名字最长为20个字母 char c[N+1];int x[N+1];int n;int pd(char *c){//判断c属于s中的第几个人     int i;    for (i = 0; i < n; i++){        if (strcmp(c,s[i]) == 0) break;    }    return i;}int main(){    int p,q;//每次p元分给q个人     char c[2*N+1];    memset(x,0,sizeof(x));    fin>>n;//读出文件 (一共有n个人)     for (int i=0;i<n;i++) fin>>s[i];//读出文件 (每个人的名字存在s数组中)     while (fin>>c>>p>>q){//每次把c的p元钱分给q个人         if ( q == 0) continue;//当分的人数为0时,无改变         int m=p/q;//判断p元钱分给q个人是否整除        x[pd(c)] -= m*q;//若整除,c将损失p元钱;若不整除,c将损失p-(p/q)*q元钱         for (int i=0;i<q;i++){//把(p/q)*q元钱分给那q个人             fin>>c;///那q个人每个人的名字             x[pd(c)] += m;//那q个人每个人盈利p/q元         }    }    for (int i=0;i<n;i++){        fout<<s[i]<<" "<<x[i]<<endl;// 写入文件     }    return 0;}
2,map

/*ID: 15189822PROG: gift1LANG: C++*/ #include<iostream>#include<map>#include<fstream>using namespace std;ifstream fin("gift1.in");ofstream fout("gift1.out");const int N = 10;string s[N+1];map<string,int>m;int main(){    int i,n;    string c;    int p,q;    fin>>n;    for (i = 0;i < n;i++) fin>>s[i];    while (fin>>c>>p>>q){        if (q == 0) continue;        m[c] -= (p - p%q);        for (i = 0;i < q;i++){            fin>>c;            m[c] += p/q;        }    }    for (i=0;i<n;i++) fout<<s[i]<<" "<<m[s[i]]<<endl;    return 0;}



原创粉丝点击