【PTA】L2-009 抢红包 (25分)

看了一遍老番茄的烂俗笑话,来整理一下这一道题,与其说是整理,不如说是碰巧做了出来.

输入格式:

输入第一行给出一个正整数N(104)即参与发红包和抢红包的总人数,则这些人从1到N编号。随后N行,第i行给出编号为i的人发红包的记录,格式如下:​)4​​),即参与发红包和抢红包的总人数,则这些人从1到N编号。随后N行,第i行给出编号为i的人发红包的记录,格式如下:

K   N1   P1   ........NK     PK      1​​P1​​NK​​PK​​

其中K(0K20)是发出去的红包个数,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;
    }
}

完工!!

原文地址:https://www.cnblogs.com/Andre/p/12355024.html