CodeForces 69C Game题解

CodeForces 69C Game题解

题目链接:http://codeforces.com/problemset/problem/69/C
弱鸡第一次发博客还有点激动…今天刷题刷到了这题,提交好多次都错了,觉得可能没有真正理解题目要求,上网搜题解也没搜到,折腾一会儿终于把这道题过了,来写篇题解。
题目大体意思,有两种加工品,一种是复合加工品,一种是基础加工品,复合加工品需要有基础加工品合成,合成后基础加工品会消失。你有k个盟友,有n种基础加工品,m种复合加工品,你的盟友一共有q次购买记录,一次购买一个物品。

 输入:第一行 k,n,m,q;
    接下来n行,每行一个字符串表示一种基础加工品,
    接下来m行,每行一个字符串表示一种复合加工品,后面跟着相应的基础加工品合成方式。
    接下来q行,每行开始一个数字,表示你的第几个盟友,后面跟一个购买的加工品;
输出:有k部分,每部分表示一个最后的物品,首先输出他所有加工品的种类(按照紫字母序),后面跟加工品的名称和数量;

注意:购买记录是根据时间线来的,合成复合加工品是边购买边合成的,一旦你一个盟友手中的基础加工品可以合成一个复合加工品,便会合成;
思路:首先把加工品的种类用数组存起来,排序,用map

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<string>
#include<queue>
#include<algorithm>
using namespace std;
int k,n,m,q;
string bas[51];
map<string,map<string,int> > comp;
map<string,int> fri[101];
string ari[101];
string com[51];
int judge(int i,map<string,int> temp)
{
    int sign=1;
    for(int p=0;p<n;p++)
    {
        if(fri[i][bas[p]]<temp[bas[p]])
        sign=0;
    }
    return sign;
}
int iscom(string te)
{
    for(int i=0;i<m;i++)
    {
        if(te==com[i])
        {
            return 1;
        }
    }
    return 0;
}
int main()
{
    cin>>k>>n>>m>>q;
    int u=0;
    for(int i=0;i<n;i++)
    {
        cin>>bas[i];
        ari[i]=bas[i];
        u++;
    }
    sort(bas,bas+n);
    for(int i=0;i<m;i++)
    {
        string ct;
        cin>>ct;
        int l=ct.length();
        ct[l-1]=' ';          //这里这个冒号我改成了空格,输出的时候注意一下
        com[i]=ct;
        ari[u++]=ct;
        string bt;
        cin>>bt;
        int nt;
        scanf("%d",&nt);
        comp[ct][bt]=nt;
        while(getchar()==',')
        {
            cin>>bt;
            scanf("%d",&nt);
            comp[ct][bt]=nt;
        }
    }                     //这一个循环把复合加工品合成关系存放到变量comp中
    sort(ari,ari+u);
    sort(com,com+m);
    for(int d=0;d<q;d++)
    {
        int num;
        string temp;
        cin>>num>>temp;
        fri[num][temp]++;  //每买一个,便用judge函数判断是否可以合成
        for(int j=0;j<m;j++)
        {
            map<string,int> temp=comp[com[j]];
            while(judge(num,temp))
            {
                int sign=1;
                for(int p=0;p<n;p++)
                {
                    if(fri[num][bas[p]]<temp[bas[p]])
                        sign=0;
                }
                if(sign==1)
                {
                    for(int p=0;p<n;p++)
                    {
                        if(fri[num][bas[p]]>=temp[bas[p]])
                        {
                            fri[num][bas[p]]-=temp[bas[p]];
                        }
                    }
                    fri[num][com[j]]++;
                }
            }

        }
    }
    for(int i=1;i<=k;i++)
    {
        queue<string> strque; //最后用queue记录最后的物品
        queue<int> que;
        for(int j=0;j<m+n;j++)
        {
            if(fri[i][ari[j]]!=0)
            {
                strque.push(ari[j]);
                que.push(fri[i][ari[j]]);
            }
        }
        cout<<que.size()<<endl;
        while(que.size())
        {
            if(iscom(strque.front()))
            {
                cout<<strque.front()<<que.front()<<endl;
            }
            else cout<<strque.front()<<' '<<que.front()<<endl;
            strque.pop();
            que.pop();
        }
    }
    return 0;
}

代码附上,有什么不对的地方还请指正。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值