看了一遍老番茄的烂俗笑话,来整理一下这一道题,与其说是整理,不如说是碰巧做了出来.
输入格式:
输入第一行给出一个正整数N(≤104)即参与发红包和抢红包的总人数,则这些人从1到N编号。随后N行,第i行给出编号为i的人发红包的记录,格式如下:)4),即参与发红包和抢红包的总人数,则这些人从1到N编号。随后N行,第i行给出编号为i的人发红包的记录,格式如下:
K N1 P1 ........NK PK 1P1⋯NKPK
其中K(0≤K≤20)是发出去的红包个数,Ni是抢到红包的人的编号,Pi(>0)是其抢到的红包金额(以分为单位),注意:对同一个人发出的红包,每个人最多只能抢一次,不能重复抢。i是抢到红包的人的编号,Pi(>0)是其抢到的红包金额(以分为单位)。注意:对于同一个人发出的红包,每人最多只能抢1次,不能重复抢。i是抢到红包的人的编号,Pi(>0)是其抢到的红包金额(以分为单位)。注意:对于同一个人发出的红包,每人最多只能抢1次,不能重复抢。
输出格式:
按照收入金额从高到低的递减顺序输出每个人的编号和收入金额(以元为单位,输出小数点后2位)。每个人的信息占一行,两数字间有1个空格。如果收入金额有并列,则按抢到红包的个数递减输出;如果还有并列,则按个人编号递增输出。
输入样例:
10
3 2 22 10 58 8 125
5 1 345 3 211 5 233 7 13 8 101
1 7 8800
2 1 1000 2 1000
2 4 250 10 320
6 5 11 9 22 8 33 7 44 10 55 4 2
1 3 8800
2 1 23 2 123
1 8 250
4 2 121 4 516 7 112 9 10
输出样例:
1 11.63
2 3.63
8 3.63
3 2.11
7 1.69
6 -1.67
9 -2.18
10 -3.26
5 -3.26
4 -12.32
在这道题中,我了解到的是algorithm标准函数库中的sort函数,可以用来根据结构体的不同变量对结构体进行排序。在此题中明确要求的是:先对总金额递减排序,如果总金额相同再对红包个数递减排序,如果红包个数还相同的话最后的区分给了编号递增排序。
在这道题中我使用的是结构体Player,定义了全局变量Player player[10000],在主函数中对player[10000]的数据进行运算。
结构体的情况:
typedef struct Player { int index; //编号 int reward;//赏金以分为单位 bool sign;//抢过的红包标记 int outmoney;//发出的红包金额以分为单位 int number;//抢到的红包个数,排序时用到 float Total;//总金额 };
sort函数用作结构体的排序时,在本题的策略采取的是sort(player,player+n,cmp);
cmp是根据需要自定义的函数。比如根据在本道题中的要求:
bool cmp(Player a,Player b) { if(a.Total!=b.Total) return a.Total>b.Total; else if(a.number!=b.number) return a.number>b.number; else return a.index<b.index; }
主函数里边分为三部分,初始化,输入红包,排序并输出结果。
初始化:
每个参与者或说是玩家player的编号index从1到n;
赏金reward即抢到的红包金额初始化为零;
红包标记sign若抢过则为1,未抢过则为0;
发出的红包金额outmoney初始化为0;
number即抢到的红包的个数初始化为0;
Total是指赏金减去发出的红包并以元为单位,保留两位小数。
for(int i=0;i<n;i++ )//初始化 { player[i].index=i+1;//给每个人编号 player[i].sign=0;//没人抢过红包 player[i].outmoney=0;//第i+1个人发出的红包金额 player[i].reward=0;//第i+1个人抢到的红包金额 player[i].number=0;//第i+1个人抢到的红包个数 }
输入红包数据:
第i个人 法了N个红包 分别是 N1号 得到P1金额的红包 N2号 得到P2金额的红包 一次类推。。。。
for(int i=0;i<n;i++ )//随后N行 { //第i+1个人发的红包 int K;//红包个数为K cin>>K; int nk,pk; for(int j=0;j<K;j++) { cin>>nk>>pk; player[i].outmoney+=pk; player[nk-1].reward+=pk; player[nk-1].number++; } }
将总金额运算一编,用sort函数对结构体排序之后再输出即可。
for(int i=0;i<n;i++) { player[i].Total=(player[i].reward-player[i].outmoney)/100.0; } sort(player,player+n,cmp); cout<<setiosflags(ios::fixed)<<setprecision(2); for(int i=0;i<n;i++) { cout<<player[i].index<<" "<<player[i].Total<<endl; }
值得注意的是,虽然有没有对setprecision(2)保留两位有效数字的操作是貌似没有影响的,但是在PTA中显示答案错误,绿绿的很难受,害得我错过了今天下午的签到,所以说,在这里想说的是include <iomanip> 和cout<<setiosflags(ios::fixed)<<setprecision(2);是需要的。
整合一下,插入代码便是:
#include <iostream> #include <algorithm> #include <iomanip> using namespace std; typedef struct Player { int index; //编号 int reward;//赏金以分为单位 bool sign;//抢过的红包标记 int outmoney;//发出的红包金额以分为单位 int number;//抢到的红包个数,排序时用到 float Total;//总金额 }; Player player[10000]; bool cmp(Player a,Player b) { if(a.Total!=b.Total) return a.Total>b.Total; else if(a.number!=b.number) return a.number>b.number; else return a.index<b.index; } int main() { int n; cin>>n; for(int i=0;i<n;i++ )//初始化 { player[i].index=i+1;//给每个人编号 player[i].sign=0;//没人抢过红包 player[i].outmoney=0;//第i+1个人发出的红包金额 player[i].reward=0;//第i+1个人抢到的红包金额 player[i].number=0;//第i+1个人抢到的红包个数 } for(int i=0;i<n;i++ )//随后N行 { //第i+1个人发的红包 int K;//红包个数为K cin>>K; int nk,pk; for(int j=0;j<K;j++) { cin>>nk>>pk; player[i].outmoney+=pk; player[nk-1].reward+=pk; player[nk-1].number++; } } for(int i=0;i<n;i++) { player[i].Total=(player[i].reward-player[i].outmoney)/100.0; } sort(player,player+n,cmp); cout<<setiosflags(ios::fixed)<<setprecision(2); for(int i=0;i<n;i++) { cout<<player[i].index<<" "<<player[i].Total<<endl; } }
完工!!