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;
}
代码附上,有什么不对的地方还请指正。