ACM-ICPC 2015 Changchun Preliminary Contest (A). Alisha's Party

传送门

题意:

有k个人去参加聚会并且拿着一定价值的礼物,主人一共开m次门,并且每次都要等到第ti个人到场才开门,每次开门放进来已经到场的人中的pi个人。谁的礼物贵谁先进来,礼物一样贵的谁先到谁先进。如果开门m次后还有人没进来,就一次性让他们全部进来。题目会给你这k个人到场的顺序和他们拿了多少钱的礼物。给你q次询问,输出第qi个进来的人是谁。

思路:

很直白的优先队列。push和pop模拟到场和进门。但是wa点也挺烦,要对t从小到大排序,比如样例中的两次开门的tp是<1,1>和<4,2>要是不排序改成<4,2><1,1>答案就不对了。如果把姓名信息存在stuct里会超时。。单开一个字符串数组,储存答案的数组存这些人的id就行了。

代码如下:

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <cmath>
#include <queue>
#include <map>
typedef unsigned int ui;
using namespace std;

int ans[150009];
char name[150009][210];
struct node
{
    int v;
    int id;
}pep[150005];
bool operator>( node a, node b )
{
    if(a.v==b.v)
        return a.id>b.id;
    return a.v<b.v;
}
priority_queue<node,vector<node>,greater<node> >pq;
//greater从小到大,但大于号里面的东西是反着定义的,所以实际是按题目要求的从大到小排列v的
//less不能编译。。。

struct tpp
{
    int t;
    int p;
}tp[150090];
bool cmp (tpp a,tpp b)
{
    return a.t<b.t;
}

int main()
{
    int t;cin>>t;
    while(t--)
    {
        memset(name,0,sizeof(name));
        memset(ans,0,sizeof(ans));
        memset(pep,0,sizeof(pep));
        int k,m,q;
        scanf("%d%d%d",&k,&m,&q);
        for(int i=1;i<=k;i++){
            scanf("%s%d",name[i],&pep[i].v);
            pep[i].id=i;
        }
        for(int i=1;i<=m;i++)
            scanf("%d%d",&tp[i].t,&tp[i].p);
        sort(tp+1,tp+1+m,cmp);//一定要按先后到场顺序来开门
        int cur=1,num=0;
        for(int i=1;i<=m;i++){//每一次开门操作
            for(int j=cur;j<=tp[i].t;j++){
                pq.push(pep[cur++]);
            }
            for(int j=1;j<=tp[i].p;j++){
                if(!pq.empty()){
                    ans[++num]=pq.top().id;
                    pq.pop();
                }
                else break;
            }
        }
        while(cur-1<k)  pq.push(pep[cur++]);//让m次开门后剩下的人进
        while(num<k){//把这些剩下的人优先队列排序后放到ans数组
            ans[++num]=pq.top().id;
            pq.pop();
        }
        for(int i=1;i<=q;i++){//就输出哇
            int b;
            scanf("%d",&b);
            if(i==1) printf("%s",name[ans[b]]);
            else printf(" %s",name[ans[b]]);
        }
        printf("\n");
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ACM-ICPC(国际大学生程序设计竞赛)是一项面向大学生的计算机编程竞赛,涉及算法和数据结构等领域。在比赛中,选手需要解决一系列编程问题,使用合适的算法和数据结构来实现正确和高效的解决方案。 对于整理ACM-ICPC模板,以下是一些建议: 1. 了解比赛要求:首先,你需要了解ACM-ICPC比赛的具体要求和规则。这包括了解比赛所涉及的算法和数据结构,以及题目的类型和难度等。 2. 收集资料:收集与ACM-ICPC相关的资料,包括经典算法和数据结构的实现代码、常见问题的解题思路等。可以参考教材、博客、论文等资源。 3. 整理模板:将收集到的资料整理成模板。可以按照算法和数据结构的分类进行整理,例如排序算法、图算法、字符串算法等。对每个模板,添加必要的注释和示例代码,以便理解和使用。 4. 测试代码:对每个模板编写测试代码,确保它们的正确性和可靠性。可以使用已知的测试用例或自行设计测试用例。 5. 更新与扩充:定期更新和扩充模板,以适应ACM-ICPC比赛中新出现的算法和数据结构。同时,根据自己的经验和理解,对模板进行优化和改进。 6. 练习和复习:在比赛之前,利用整理好的模板进行练习和复习。尝试解决一些经典问题,使用模板中的算法和数据结构进行实现,并进行优化。 希望这些建议对你整理ACM-ICPC模板有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值