PTAL2-009 抢红包 (25分)

Posted andre

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PTAL2-009 抢红包 (25分)相关的知识,希望对你有一定的参考价值。

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

 

 

技术图片

 

 

 在这道题中,我了解到的是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;
    }
}

完工!!

以上是关于PTAL2-009 抢红包 (25分)的主要内容,如果未能解决你的问题,请参考以下文章

笔试题--红包算法,给定一个红包总金额和分红包的人数,输出每个人随机抢到的红包数量。

微信抢红包过期失效实战案例

分红包算法(Python)

微信高并发抢红包秒杀实战案例

苹果手机怎么安装自动抢红包神器

切西瓜法实现微信抢红包功能