USACO Section 1.1 Greedy Gift Givers

题目描述

一组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让我们保留每个人的“给”(钱)的表:

dave laura owen vick amr
0 0 0 0 0

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

-200+2 66 66 66 0

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

-198+500 66 66-500 66 0

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

302 66 -434+75 66+75 -150

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

302 66 -359 141 -150

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

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

解题思路

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

解题代码

1,定义一个函数

/*
ID: 15189822
PROG: gift1
LANG: 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: 15189822
PROG: gift1
LANG: 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;
}



猜你喜欢

转载自blog.csdn.net/YanLucyqi/article/details/72772236