[pre]2 ring 1 sword 2 1 knife 3: ring 1, sword 1 1 medicine 1 4 +100 +ring +sword +knife 1 shoe 0 1 wing 1: 1 medicine 1 3 +10 +shoe +wing 1 shoe 0 1 wing 1: 1 medicine 1 4 +10 +shoe +wing -wing 1 shoe 1 1 wing 1: shoe 1 1 medicine 1 8 +100 +shoe +shoe +shoe +shoe +shoe +medicine +medicine [/pre]
[pre]Case 1: 94 1 knife: 1 Case 2: 9 2 shoe: 1 wing: 1 Case 3: 10 1 shoe: 1 Case 4: 94 6 medicine: 1 shoe: 1 shoe: 1 shoe: 1 shoe: 1 shoe: 1 [/pre]
变态模拟,各种蛋疼,无力吐槽,内牛满面。。。。
跪了将近一天了,虽然也犯了一些SB错误,但是这题的描述严重有问题。
先翻译一下此题:
题目大意:
1、初始状态一个背包,6个格子,一个钱包,一开始背包是空的,钱包也是空的
2、一共3种装备
3、普通装备:一个普通装备在背包占一个格子,可以直接买,价值就是它的价钱
4、合成装备:一个占一格,不可以直接买,根据处方合成,必须有足够的处方上的装备
以及足够的金币,它的价值是所有原料装备价值和合成所要的金币和,可以由普通装备
和合成装备合成。
5、消耗装备:一种占一格,可以直接买。如果要卖这种装备,必须卖掉所有该装备
还要注意:
1、背包满了就不能买东西了(可以合成)
2、 When a mixture equipment is get, the mixture equipment of recipe in you backpack will disappear:当合成了一个合成装备,它的处方会消失,即只能合成一次//这句话难道翻译错了?这样处理是错的
3、如果某操作非法,则该操作无效。不影响背包和金币。
4、初始背包空的,无金币
5、金币数不能为负
输入:
第一行0<=N1<=20,普通装备的数量
接下来N1行 每行一个字符串一个数字,分别表示普通装备的名字和价钱
然后0<=N2<=20,混合装备的数量
接下来N2行,每行先一个字符串一个数字,分别表示混合装备的名字和合成花费
然后给一个列表,表示合成此装备的原料及数量,总数不超过6个
再给一个0<=N3<=20,表示消耗装备的数量
接下来N3行,每行一个字符串一个数字,分别表示消耗装备的名字和价钱
再给一个M,表示操作总数
一共三种操作:
1:++num,表示得到num的金钱(0<=num<=100)
2:++str,表示想得到名叫str的装备
3:--str,表示想卖掉叫str的装备,得到相应的金币
每个名字都由小写字母组成,长度不超过15,每种装备的价钱为不超过1000的正整数
输出:
先输出Case #
然后输出最后的金币数
再输出还有几种装备
依次字典序输出这k种装备
输出空行
题目分析:模拟。输入就比较搞人,特别是合成装备,可以不需要原料直接合成的,那么就直接当普通装备处理。还有合成装备的原料的个数可以为0的。。。就是说需要这种原料,但是并不消耗这种原料。还有买消耗装备的时候,必须先买再合并的,如果背包是满的也是不能买的。
这算是一道比较好的模拟,但是坑爹的题目描述瞬间拉低了这题的档次。。
详情请见代码:
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct norequ { char name[16]; int price; }normal[21]; struct obj { char name[16]; int num,price; friend bool operator < (struct obj a,struct obj b) { return strcmp(a.name,b.name) < 0; } }Obj[7]; int total; bool del[10]; struct mix { char name[16]; int cost; int cnt; bool flag; int num[6];//原料数量 char sname[6][16];//原料名 }mixture[21]; struct con { char name[16]; int price; }consume[21]; int gold; int m; char equp[20]; int nornum,mixnum,connum; void show() { printf("Let's show:\n"); int i,j; printf("normal:\n"); for(i = 0;i < nornum;i ++) printf("%s %d\n",normal[i].name,normal[i].price); printf("\n"); printf("mixture:\n"); for(i = 0;i < mixnum;i ++) { printf("%s %d\n",mixture[i].name,mixture[i].cost); printf("the %dth mixture is consist of:\n",i); for(j = 0;j < mixture[i].cnt;j ++) printf("%s %d\n",mixture[i].sname[j],mixture[i].num[j]); } printf("\n"); printf("consume:\n"); for(i = 0;i < connum;i ++) { printf("%s %d\n",consume[i].name,consume[i].price); } printf("Show off\n"); } void output(int cas) { printf("Case %d:\n",cas); printf("%d\n",gold); printf("%d\n",total); sort(Obj,Obj + total); for(int i = 0;i < total;i ++) printf("%s: %d\n",Obj[i].name,Obj[i].num); putchar(10); } int find(char sss[])//找到物品种类 { int i; for(i = 0;i < nornum;i ++) { if(strcmp(sss,normal[i].name) == 0) return i; } for(i = 0;i < mixnum;i ++) { if(strcmp(sss,mixture[i].name) == 0) return 30 + i; } for(i = 0;i < connum;i ++) { if(strcmp(sss,consume[i].name) == 0) return 60 + i; } return -1; } int canmix(int id) { if(mixture[id].cnt == 0) return 0; int i,j,k; int ret = 0; bool lll = false; for(i = 0;i < mixture[id].cnt;i ++) { k = mixture[id].num[i]; for(j = 0;j < total;j ++) { if(strcmp(mixture[id].sname[i],Obj[j].name) == 0) { if(Obj[j].num <= mixture[id].num[i])//合成的时候 {//有原料消耗,才能将合成物品放进背包 lll = true; } k -= Obj[j].num; } if(k <= 0)//原料足够 break; } if(k > 0)//原料是不够的 return -1; } if(lll = false && total == 6)//如果背包是满的但是原料不能腾出位置,也是不能合成的 return -1; return 0; } void mixit(int id) { if(mixture[id].cnt == 0) return; int i,j,k; memset(del,false,sizeof(del)); for(i = 0;i < mixture[id].cnt;i ++) { k = mixture[id].num[i]; if(!k) continue; for(j = 0;j < total;j ++) { if(strcmp(mixture[id].sname[i],Obj[j].name) == 0) { if(Obj[j].num > k) { Obj[j].num -= k; k = 0; } else { del[j] = true;//要删除的做标记 k -= Obj[j].num; } if(k == 0) break; } } } int pos = 0; for(i = 0;i < total;i ++) { if(del[i] == false) Obj[pos ++] = Obj[i]; } total = pos; } int getprice(int type)//因为合成物品的原料也可以是合成物品,要递归计算价值 { if(type < 30) return normal[type].price; if(type >= 60) return consume[type - 60].price; int i; int ret = 0; for(i = 0;i < mixture[type - 30].cnt;i ++) { int tmp = find(mixture[type - 30].sname[i]); ret += mixture[type - 30].num[i] * getprice(tmp); } return ret + mixture[type - 30].cost; } void buy(int type) { if(type < 30) { if(total == 6 || gold < normal[type].price) return; strcpy(Obj[total].name,normal[type].name); Obj[total].num = 1; Obj[total].price = normal[type].price; total ++; gold -= normal[type].price; return; } if(type >= 30 && type < 60)// mixture[type - 30].flag) { if(gold < mixture[type - 30].cost)//只需要付合成的钱 return; int tmp = canmix(type - 30); if(tmp == -1) return; tmp = getprice(type); gold -= mixture[type - 30].cost; mixit(type - 30); Obj[total].price = tmp; Obj[total].num = 1; strcpy(Obj[total].name,mixture[type - 30].name); total ++; mixture[type - 30].flag = false;//only once } if(type >= 60) { if(total == 6 || gold < consume[type - 60].price)//消耗品先买再合并 return; gold -= consume[type - 60].price; for(int i = 0;i < total;i ++) { if(strcmp(Obj[i].name,equp) == 0) { Obj[i].num ++; return; } } strcpy(Obj[total].name,consume[type - 60].name); Obj[total].num = 1; Obj[total].price = consume[type - 60].price; total ++; return; } } void sell(int type) { int i; for(i = 0;i < total;i ++) { if(strcmp(equp,Obj[i].name) == 0) break; } if(i == total)//unfind return; if(type < 30) { gold += Obj[i].price; for(int j = i + 1;j < total;j ++) Obj[j - 1] = Obj[j]; total --; return; } if(type >= 30 && type < 60) { gold += Obj[i].price; for(int j = i + 1;j < total;j ++) Obj[j - 1] = Obj[j]; total --; return; } if(type >= 60) { gold += Obj[i].price * Obj[i].num; for(int j = i + 1;j < total;j ++) Obj[j - 1] = Obj[j]; total --; return; } } int main() { int i; char c; char op[20]; int cas = 0; while(scanf("%d",&nornum) != EOF) { gold = 0; total = 0; for(i = 0;i < nornum;i ++) { scanf("%s%d",normal[i].name,&normal[i].price); } scanf("%d",&mixnum); getchar(); for(i = 0;i < mixnum;i ++) { char str[200]; gets(str);//还好有sscanf int p = 0; int tmp = 0; sscanf(str + p,"%s%d",mixture[i].name,&mixture[i].cost); while(str[p] && str[p] != ' ') p ++; p ++; while(str[p] && str[p] != ' ') p ++; while(sscanf(str + p,"%s%d",mixture[i].sname[tmp],&mixture[i].num[tmp]) == 2) { tmp ++; if(mixture[i].num[tmp - 1] == 0) tmp --; while(str[p] && str[p] == ' ') p ++; while(str[p] && str[p] != ' ') p ++; p ++; while(str[p] && str[p] != ' ') p ++; } mixture[i].cnt = tmp; mixture[i].flag = true; } scanf("%d",&connum); for(i = 0;i < connum;i ++) { scanf("%s%d",consume[i].name,&consume[i].price); } //show(); scanf("%d",&m); getchar(); while(m --) { gets(op); if(isdigit(op[1])) { sscanf(op + 1,"%d",&i); if(op[0] == '+') gold += i; else { if(gold >= i) gold -= i; } } else { sscanf(op + 1,"%s",equp); int type = find(equp); if(type == -1) continue; if(op[0] == '+') buy(type); else sell(type); } } output(++ cas); } return 0; } //0MS 260K /* 2 ring 1 sword 2 1 knife 3: ring 1, sword 1 1 medicine 1 5 +100 +ring +ring +sword +knife 2 ring 1 sword 2 1 knife 3: ring 1, sword 1 1 medicine 1 4 +100 +ring +sword +knife 1 shoe 0 1 wing 1: 1 medicine 1 3 +10 +shoe +wing 1 shoe 0 1 wing 1: 1 medicine 1 4 +10 +shoe +wing -wing 1 shoe 1 1 wing 1: shoe 1 1 medicine 1 8 +100 +shoe +shoe +shoe +shoe +shoe +medicine +medicine 2 ring 1 sword 2 1 knife 3: ring 1, sword 1 1 medicine 1 4 +100 +ring +sword +knife 2 ring 1 sword 2 1 knife 3: ring 2, sword 1 1 medicine 1 5 +100 +ring +ring +sword +knife 2 ring 1 sword 2 1 knife 3: ring 1, sword 1 1 medicine 1 5 +100 +ring +sword +knife -knife 2 ring 1 sword 2 1 knife 3: ring 1, sword 1 1 medicine 1 5 +100 +ring +sword +knife -sword 1 shoe 0 1 wing 1: 1 medicine 1 3 +10 +shoe +wing 1 shoe 0 1 wing 1: 1 medicine 1 4 +10 +shoe +wing -wing 1 shoe 1 1 wing 1: shoe 1 1 medicine 1 7 +100 +shoe +shoe +shoe +shoe +medicine +medicine 1 shoe 1 1 wing 1: shoe 1 1 medicine 1 8 +100 +shoe +shoe +shoe +shoe +medicine +medicine -medicine */