X-man

导航

hdu 4269 Defend Jian Ge

#include <cctype>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
using namespace std;
#define PB push_back
#define MP make_pair
typedef vector<pair<string,int> > VP;
vector<string> mixture;
VP backpack;
map<string, VP>recipe;
map<string,int> value,state,type,cost;
int gold;
inline void init(void)
{
    gold=0;
    backpack.clear();
    recipe.clear();
    mixture.clear();
    value.clear();
    state.clear();
    type.clear();
    cost.clear();
}
inline VP get_recipe(void)
{
    int cnt;
    string line,item;
    stringstream ss;
    ss.clear();
    getline(cin,line);
    ss<<line;
    VP res;
    while(ss>>item)
    {
        if(!islower(item[0])) continue;
        ss>>cnt;
        res.PB(MP(item,cnt));
    }
    return res;
}
int get_value(string s)
{
    int res=0;
    VP tmp = recipe[s];
    for(size_t i=0; i<tmp.size(); i++)
    {
        if(value.find(tmp[i].first)==value.end())
            res+=get_value(tmp[i].first)*tmp[i].second;
        else res+=value[tmp[i].first]*tmp[i].second;
    }
    return res;
}
inline void read(int n,int t)
{
    string item;
    for(int i=0,price; i<n; i++)
    {
        cin>>item>>price;
        value[item]=price;
        type[item]=t;
    }
}
inline void read_and_cal(int n)
{
    string item;
    for(int i=0,price; i<n; i++)
    {
        cin>>item>>price;
        cost[item]=price;
        recipe[item]=get_recipe();
        mixture.PB(item);
        type[item]=2;
    }
    for(int i=0; i<n; i++)
    {
        item=mixture[i];
        value[item]=cost[item]+get_value(item);
    }
}
inline int get_num(string s)
{
    int res=0;
    for(size_t i=0; i<s.size(); i++) res=res*10+(s[i]&15);
    return res;
}
inline void update(void)
{
    backpack.clear();
    for(map<string,int>::iterator it=state.begin(); it!=state.end(); it++)
    {
        if(type[it->first]==3) backpack.PB(MP(it->first,it->second));
        else
        {
            for(int i=0; i<(it->second); i++)
                backpack.PB(MP(it->first,1));
        }
    }
}
inline void get_item(string s)
{
    if(type[s]==2)
    {
        if(cost[s]>gold) return;
        VP tmp=recipe[s];
        for(VP::iterator it=tmp.begin(); it!=tmp.end(); it++)
            if(state[(*it).first]<(*it).second) return;
        for(VP::iterator it=tmp.begin(); it!=tmp.end(); it++)
        {
            state[(*it).first]-=(*it).second;
            if(!state[(*it).first]) state.erase((*it).first);
        }
        gold-=cost[s];
    }
    else
    {
        if(value[s]>gold || backpack.size()==6) return;
        gold-=value[s];
    }
    state[s]++;
    update();
}
inline void sell_item(string s)
{
    if(state.find(s)==state.end()) return;
    if(type[s]==3)
    {
        gold+=value[s]*state[s];
        state.erase(state.find(s));
    }
    else
    {
        gold+=value[s];
        if(state[s]==1) state.erase(state.find(s));
        else state[s]--;
    }
    update();
}
inline void output(int c)
{
    cout<<"Case "<<c<<":\n"<<gold<<'\n'<<backpack.size()<<'\n';
    sort(backpack.begin(),backpack.end());
    for(VP::iterator it=backpack.begin(); it!=backpack.end(); it++)
        cout<<(*it).first<<": "<<(*it).second<<'\n';
    cout<<'\n';
}
int main(void)
{
    int n1,n2,n3,m;
    string opt,arg;
    for(int cas=1; cin>>n1; cas++)
    {
        init();
        read(n1,1);
        cin>>n2;
        read_and_cal(n2);
        cin>>n3;
        read(n3,3);
        for(cin>>m; m--;)
        {
            cin>>opt;
            arg=opt.substr(1,opt.size()-1);
            if(isdigit(opt[1])) gold+=get_num(arg);
            else if(opt[0]=='+') get_item(arg);
            else sell_item(arg);
        }
        output(cas);
    }
    return 0;
}

题意是模拟三种装备的购买和合成,需要注意的是:

1.当物品栏满时只能合成装备,并且合成后的装备也要占一个,所以只要合成卷轴就能合成的装备只有在当前的物品栏没有满时才能合成。
2.消耗装备在物品栏满时无法再购买,即使物品栏里有相同的消耗装备,因为题意默认先购买再合并,在这点上我果断被坑了。
3.合成装备的“原料”只能是基本装备和合成装备。
4.除消耗装备外其它装备每个都要占一个物品栏。

posted on 2013-08-27 15:18  雨钝风轻  阅读(292)  评论(0编辑  收藏  举报