hdu4269 Defend Jan Ge changchun online 恶心模拟

各种恶心。。  直接贴代码了。。。

比较混乱。。  直接用STL或者字符串hash等 会更简洁 更容易....

Problem Description
Defend Jian Ge, an interesting RPG map in WAR3, has a very complete equipment system as a mini RPG game.
In the game, each player has a backpack which has 6 grids and some gold reserves. There are three kinds of equipments in the game.
1. Normal equipment: Each equipment occupies one grid in the backpack and the player can buy it directly. The value of the normal equipment is equal to its price.
2. Mixture equipment: Each equipment occupies one grid in the backpack and the player can only get it through the synthesis of the corresponding recipe. If you have enough equipment of recipes in your backpack and gold to pay synthesis cost, you can get it. The value of the mixture equipment is equal to the sum of all equipments’ value in the recipe plus the synthesis cost. A mixture equipment can be made from several normal equipments and mixture equipments.
3. Consume equipment: A kind of equipment must occupy one grid and the player can buy it directly. That is to say, if you have a number of consume equipments, they must be in one grid. The value of each consume equipment is equal to its price, and when you want to sell this kind of equipment, you must sell the whole grid's equipments at the same time.



You should pay attention:
1. When the backpack is full, you cannot buy anything.
2. When a mixture equipment is get, the mixture equipment of recipe in you backpack will disappear.
3. If one operation is illegal, there is nothing happened in your backpack and gold.
4. Initially, there is nothing in your backpack and you have 0 gold.
5. The gold you have cannot be a negative number.

As a DS programmer, you want to simulate the dynamic states in your backpack by program. Now you have initial state and several operations, you wonder the final state.
 

Input
There are multiple test cases.
The first line contains an integer N1 (0 <= N1 <= 20) indicating the kind of normal equipment.
The next N1 lines each line contains a string and an integer indicating the name of this normal equipment and its price respectively.
**Format: str num
The following line contains an integer N2 (0 <= N2 <= 20) indicating the kind of mixture equipment.
Each of the next N2 lines begins with a string and an integer indicating the name of this mixture equipment and its synthesis cost. Following, the synthesis recipe of this kind of equipment: some pairs of string and integer indicating which kind of equipment and the number you need to synthesis.
**Format: str num: str1 num1, str2 num2, ... , strn numn (num1 + num2 + … +numn<=6 and numi >= 0 (1 <= i <= n))
The next line contains an integer N3 (0 <= N3 <= 20) indicating the kind of consume equipment.
Each of the next N3 lines contains a string and an integer indicating the name of this consume equipment and it's price.
**Format: str num
The next line contains an integer M (0 <= M <= 100) indicating the number of operation.
Each of the next M lines contains an operation.
There are three kinds of operation:
1. +num indicating you get num gold (0 <= num <= 1000).
2. +str indicating you want to get an equipment whose name is str.
3. -str indicating you want to sell the equipment whose name is str. If you sell the equipment, you can get gold that is the same to its value.

There is a blank line after each case.
All strings of name only contain lowercase character and its length is no more than 15. The price of the equipment is a non-negative integer which is no more than 1000.
 

Output
For each case you should output several lines.
The first line output "Case " + case number + ":".
The next line output an integer indicating the number of gold at last.
The next line output an integer k indicating how many grids occupied.
Each of the next k lines contain a string and an integer indicating the name and the number of the equipment. You should output according to the lexicographic.
**Format: str: num

You can get more details from the sample below.
NOTE: Output a blank line after each test case.
 

Sample Input
  
  
[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]
 

Sample Output
  
  
[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]
 

Source

#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
#define MAX 26
#define BUG puts("GF")
using namespace std;
const bool GF1 = true;
int Gold,leftG;
char stmp[10000];
int N_nme, N_mxe, N_cse;
char name_nme[22][30], name_mxe[22][30], name_cse[22][30];
int  price_nme[22], price_mxe[22], price_cse[22];

char mx_part_name[22][60][30];
int mx_tt_part[22], mx_part_need[22][60];

struct OT{
    string os;
    int ctr;
    bool operator < (const OT &a) const{
        return os<a.os;
    }
};

set<OT> Set;
map<string,int> type;
map<string,int> priceCSE;
map<string,int> priceNME;
map<string,int> priceMXE;
map<string,int> MXEID;

typedef struct TrieNode {
    int nCount;
    struct TrieNode *next[MAX];
}TrieNode;

TrieNode Memory[100000];
int allocp =0;

TrieNode *CreateTrieNode() {
    int i;
    TrieNode *p;
    p = &Memory[allocp++];
    p->nCount = 0;
    for(i =0 ; i < MAX ; i++) {
        p->next[i] = NULL;
    }
    return p;
}


void InsertTrie(TrieNode * &pRoot , char*s) {
    int i, k;
    TrieNode *p;
    if(!(p = pRoot)) {
        p = pRoot = CreateTrieNode();
    }
    i = 0;
    while(s[i]) {
        k = s[i++] - 'a';
        if( ! p->next[k]) p->next[k] = CreateTrieNode();
        p = p->next[k];
    }
    p->nCount += 1;
}

void DeletTrie(TrieNode * &pRoot, char *s, int dn)
{
    TrieNode *p;
    int i , k;
    if(!(p = pRoot)) {
        return ;
    }
    i = 0;
    while(s[i]) {
        k = s[i++] -'a';
        if(p->next[k] == NULL) return ;
        p = p->next[k];
    }
    p->nCount -= dn;
    return ;
}

int SearchTrie(TrieNode * &pRoot , char*s) {
    TrieNode *p;
    int i , k;
    if(!(p = pRoot)) {
        return 0;
    }
    i = 0;
    while(s[i]) {
        k = s[i++] -'a';
        if(p->next[k] == NULL) return 0;
        p = p->next[k];
    }
    return p->nCount;
}


TrieNode * box = NULL;

void init()
{
    box = NULL;
    allocp = 0;
    Gold = 0;
    leftG = 6;
    //N_nme = N_mxe = N_cse = 0;    
    type.clear();
    priceNME.clear();
    priceCSE.clear();
    priceMXE.clear();
    MXEID.clear();
    Set.clear();
    memset(mx_tt_part,0,sizeof(mx_tt_part));
    memset(name_nme,0,sizeof(name_nme));
    memset(name_mxe,0,sizeof(name_mxe));
    memset(name_cse,0,sizeof(name_cse));
    memset(price_nme,0,sizeof(price_nme));
    memset(price_mxe,0,sizeof(price_mxe));
    memset(price_cse,0,sizeof(price_cse));
    memset(mx_part_name,0,sizeof(mx_part_name));
    memset(mx_part_need,0,sizeof(mx_part_need));
}
void input()
{
    getchar();
    for(int i=0; i<N_nme; ++i)
    {    
        scanf("%s %d",name_nme[i],&price_nme[i]);
        string nnnn1;
        nnnn1 = (name_nme[i]);
        type[nnnn1] = 1;
        priceNME[nnnn1] = price_nme[i];
    }
    
    scanf("%d",&N_mxe);
    getchar();
    for(int i=0; i<N_mxe; ++i)
    {        
        gets(stmp);
        int len = strlen(stmp);
        int cur = 0;
        sscanf(stmp,"%s%d",name_mxe[i],price_mxe+i);
        string sk(name_mxe[i]);
        priceMXE[sk] = price_mxe[i];
        MXEID[sk] = i;
        type[sk] = 2;
        while( (*(stmp+cur)) != ':') ++cur;
        for(++cur;cur<len;++cur)
        {
            sscanf(stmp+cur,"%s%d",mx_part_name[i][ mx_tt_part[i] ],&mx_part_need[i][ mx_tt_part[i] ]);
            mx_tt_part[i] ++;
            while(cur < len && (*(stmp+cur)) != ',') ++cur;
            ++cur;
        }    
    }
    
    scanf("%d",&N_cse);
    getchar();
    for(int i=0; i<N_cse;++i)
    {
        scanf("%s%d",name_cse+i, price_cse+i);
        string nnnn3(name_cse[i]);
        type[nnnn3] = 3;
        priceCSE[nnnn3] = price_cse[i];
    }    
}

void obtain(char * name)
{
    string mm(name);
    int swich2 = type[mm];
    if(swich2 == 1 && Gold >= priceNME[mm] && leftG >0)
    {
        Gold -= priceNME[mm];
        leftG -= 1;
        InsertTrie(box,name);
        return ;
    }
    if(swich2 == 3 && Gold >= priceCSE[mm] && leftG >0)
    {
        int ex = SearchTrie(box,name);
        if( ex == 0 )
        {
            if(leftG >=1)
            {
                leftG -= 1;
                Gold -= priceCSE[mm];
                InsertTrie(box,name);
            }
            else return ;
        }
        else if (ex != 0)
        {
            Gold -= priceCSE[mm];
            InsertTrie(box,name);
        }
    }
    if(swich2 == 2 && Gold >= price_mxe[MXEID[mm]])
    {
        int ffg = 1;
        for(int i=0; i<mx_tt_part[ MXEID[mm] ];++i)
        {
            if( SearchTrie(box,mx_part_name[MXEID[mm]][i]) < mx_part_need[MXEID[mm]][i])
            {
                ffg = 0;     break;
            }
        }
        if(ffg)
        {
            InsertTrie(box,name);            
            Gold -= price_mxe[MXEID[mm]];
            leftG -= 1;
            for(int i=0; i<mx_tt_part[ MXEID[mm] ];++i)
                {
                    if(mx_part_need[MXEID[mm]][i] == 0) continue ;
                    string jj(mx_part_name[ MXEID[mm] ][i]);
                    int swch = type[jj];
                    DeletTrie(box,mx_part_name[MXEID[mm]][i],mx_part_need[MXEID[mm]][i]);
                    if( swch == 1 || swch == 2)
                    {
                        leftG += mx_part_need[MXEID[mm]][i];
                    }
                    if( swch == 3)
                    {
                        if(SearchTrie(box,mx_part_name[MXEID[mm]][i]) == mx_part_need[MXEID[mm]][i])
                        {
                            leftG += 1;
                        }
                    }
                }
        }
        return ;
    }
}


void sold(char * name)
{
    int num9 = SearchTrie(box, name);
    if( num9 == 0) return ;
    
    leftG += 1;
    
    string etmp(name);
    int swich = type[etmp];
    if(swich == 3)
    {
         Gold += num9 * priceCSE[etmp];
         DeletTrie(box,name,num9);
         return ;
    }
    if(swich == 1)
    {
        Gold += priceNME[etmp];
        DeletTrie(box,name,1);
        return ;
    }
    if(swich == 2)
    {
        DeletTrie(box,name,1);
        stack<string> Stak;
        Stak.push(etmp);
        string fobl;
        while(! Stak.empty())
        {
            etmp = Stak.top();
            Stak.pop();
            Gold += priceMXE[etmp];
            for(int i=0; i<mx_tt_part[ MXEID[etmp] ]; ++i)
            {
                fobl = mx_part_name[MXEID[etmp]][i];
                if(type[ fobl ] == 2) Stak.push(fobl);
                else if(type[fobl] == 1) Gold+= priceNME[fobl]*mx_part_need[MXEID[etmp]][i];
                else if(type[fobl] == 3) Gold+= priceCSE[fobl]*mx_part_need[MXEID[etmp]][i];
            }
        }
        return;
    }
}

void operate()
{
    char flag = 0;
    getchar();
    char op = getchar();
    char reds[30];
    int getgold = -999;
     scanf("%s",reds);
     if(reds[0]>='0' && reds[0]<='9')
     {
         sscanf(reds,"%d",&getgold);
    }

    if(op == '+' && getgold >=0)
    {
        Gold += getgold; return;        
    }
    if(op == '+' && getgold < 0)
    {
        obtain(reds); return ;
    }
    if(op == '-' && getgold <0)
    {
        sold(reds); return ;
    }
    return;
}

int main()
{
    int CSN = 1;
    while(scanf("%d",&N_nme) != EOF)
    {
        int M;
        init();
        input();
        scanf("%d",&M);
        for(int i = 1; i <= M; ++i)
        {
            operate();
        }
        getchar();
        cout<<"Case "<<CSN++<<':'<<endl;
        cout<<Gold<<endl;
        cout<<6-leftG<<endl;
        
        for(int i=0;i<N_nme;++i)
        {
            int sp;
            if(sp = SearchTrie(box,name_nme[i]))
            {
                OT foobar;
                foobar.os = name_nme[i];
                foobar.ctr = sp;
                Set.insert(foobar);
            }
        }
        for(int i=0;i<N_mxe;++i)
        {
            int sp1;
            if(sp1 = SearchTrie(box,name_mxe[i]))
            {
                OT foobar;
                foobar.os = name_mxe[i];
                foobar.ctr = sp1;
                Set.insert(foobar);
            }
        }
        for(int i=0;i<N_cse;++i)
        {
            int sp;
            if(sp = SearchTrie(box,name_cse[i]))
            {
                OT foobar;
                foobar.os = name_cse[i];
                foobar.ctr = sp;
                Set.insert(foobar);
            }
        }
        set<OT>::iterator it = Set.begin();
        for(;it != Set.end();++it)
        {
            if(type[(*it).os] == 3)
            cout<< (*it).os<<": "<<(*it).ctr<<endl;
            else
            {
                for(int i=0;i<(*it).ctr;++i)
                cout<< (*it).os<<": "<<1<<endl;
            }
        }
        cout<<endl;        
    }
    return 0;
}

黄牛的码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <sstream>
#include <map>
#include <cctype>
using namespace std;

struct Item {
	int prz, typ, num;
	int tn;
	int us[65][2];
}a[110];

struct Name {
	char name[20];
	bool operator < (const Name &b) const {
		return strcmp(name, b.name) == -1;
	}
}b;

map <Name, int> mmap;
map <Name, int>::iterator it;

int id, fg;
int n;
char s[10000], ch, bf[1000];
int cnt, gold, p;

int main(void) {

freopen("data.in", "r", stdin);

	int cas = 0;
	while (~scanf("%d", &n)) {
		mmap.clear();
		cnt = gold = 0;
		fg = 0;
		cas++;
		while (n--) {
			scanf("%s", b.name);
			it = mmap.find(b);
			if (it == mmap.end()) {
				mmap.insert(pair<Name, int>(b, fg++));
				id = fg - 1;
			} else
				id = it->second;
			scanf("%d", &a[id].prz);
			a[id].typ = 0;
			a[id].num = a[id].tn = 0;
		}
		scanf("%d", &n);
		while (n--) {
			scanf("%s", b.name);
			it = mmap.find(b);
			if (it == mmap.end()) {
				mmap.insert(pair<Name, int>(b, fg++));
				id = fg - 1;
			} else
				id = it->second;
			scanf("%d", &a[id].prz);
			a[id].typ = 1;
			a[id].num = a[id].tn = 0;
			getchar();
			cin.getline(s, 10000);
			stringstream ss(s);
			while (ss >> b.name) {
				it = mmap.find(b);
				if (it == mmap.end()) {
					mmap.insert(pair<Name, int>(b, fg++));
					it = mmap.find(b);
				}
				a[id].us[a[id].tn][0] = it->second;
				ss >> a[id].us[a[id].tn][1] >> bf;
				a[id].tn++;
			}
		}
		scanf("%d", &n);
		while (n--) {
			scanf("%s", b.name);
			it = mmap.find(b);
			if (it == mmap.end()) {
				mmap.insert(pair<Name, int>(b, fg++));
				id = fg - 1;
			} else
				id = it->second;
			scanf("%d", &a[id].prz);
			a[id].typ = 2;
			a[id].num = a[id].tn = 0;
		}
		scanf("%d", &n);
		while (n--) {
			//cout << "Gold = " << gold << endl;
			scanf("%s", s);
			if (isdigit(s[1])) {
				p = 0;
				for (int i = 1; s[i] != 0; i++)
					p = p*10 + s[i] - 48;
				if (s[0] == '+')
					gold += p;
				else if (gold >= p)
					gold -= p;
			} else {
				sscanf(s+1, "%s", b.name);
				it = mmap.find(b);
				if (it == mmap.end())
					continue;
				id = it->second;
				if (s[0] == '+') {
					if (a[id].typ == 0 && cnt < 6 && gold >= a[id].prz) {
						a[id].num++;
						cnt++;
						gold -= a[id].prz;
					} else if (a[id].typ == 2 && cnt < 6 && gold >= a[id].prz) {
						if (a[id].num == 0)	cnt++;
						a[id].num++;
						gold -= a[id].prz;
					} else if (a[id].typ == 1 && gold >= a[id].prz) {
						bool flag = 1;
						int grid = 1;
						for (int i = 0; i < a[id].tn && flag; i++) {
							if (a[a[id].us[i][0]].num < a[id].us[i][1])
								flag = 0;
							else
								grid -= a[id].us[i][1];
						}
						if (flag && cnt + grid <= 6) {
							gold -= a[id].prz;
							cnt += grid;
							a[id].num++;
							for (int i = 0; i < a[id].tn; i++)
								a[a[id].us[i][0]].num -= a[id].us[i][1];
						}
					}
				} else if (a[id].num != 0) {
					if (a[id].typ == 0) {
						cnt--;
						a[id].num--;
						gold += a[id].prz;
					} else if (a[id].typ == 1) {
						cnt--;
						a[id].num--;
						int cost = a[id].prz;
						for (int i = 0; i < a[id].tn; i++)
							cost += a[id].us[i][1] * a[a[id].us[i][0]].prz;
						gold += cost;
					} else {
						cnt--;
						gold += a[id].prz * a[id].num;
						a[id].num = 0;
					}
				}
			}
		}
		printf("Case %d:\n%d\n%d\n", cas, gold, cnt);
		for (it = mmap.begin(); it != mmap.end(); it++) {
			for (int i = 0; i < a[it->second].num; i++) {
				if (a[it->second].typ != 2)
					printf("%s: 1\n", (it->first).name);
				else {
					printf("%s: %d\n", (it->first).name, a[it->second].num);
					break;
				}
			}
		}
		printf("\n");
	}
	return 0;
}

我最自信的码风被晃动了..


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
前言:其实一年前研究mpq加密的时候就有这个想法,后来对加密失去兴趣,没有应用而已。 先从mpq读取(和写入)说起。市面上的软件大致有以下几种方法: 0.listfile式。0这个数字说明了它的原始。如果mpq没有用listfile明确叙述自己的文件组成,它就无法读取其中的文件。怎么说呢,这就好像只要犯人不招认,自己也认为犯人无罪的笨蛋侦探一样,严谨到无聊。典型例子不是别人,正是大名鼎鼎的WorldEditor地图编辑器。对付这种软件,删掉listfile就一切安好。 1.小白式。这种软件基本上用自制的dll(因为暴雪只提供了读mpq的storm.dll,没有写入),按照mpq文件格式非常循规蹈矩地一步步读出内容。问题在于mpq数据稍有不对就会导致崩溃。例如header中mpq文件大小这项数据,war3读地图的时候根本不管,所以怎么写都不影响地图工作,但这类工具却会照着此数据读图,然后掉进番茄海的无底深渊。 典型例子是winmpq和mpqmaster。 2.storm式。以火龙hke为代表。这类mpq软件用暴雪提供的storm.dll读取mpq,读取方式和暴雪一致。由于mpq文件被设计成“知道文件名(含路径)可以很容易读取,但扫描所有文件路径却几乎不可能”的格式,war3在读地图时只用在需要的时候读指定文件就ok,所以这类编辑器也模拟war3读地图的方式,逐渐推算出“需要的文件”从而读出地图中近乎全部文件,只要在物编中涉及到或jass中提及的路径,都会检测对应的文件并列在表中。这是一种近乎无敌的方法,不会报错(否则war3也玩不了这图),且war3map.j等固定文件必然被扫描出来(否则war3自己也找不到)。 然后是重点: 但这里有个致命问题——不管是火龙还是war3,不可能预知到游戏过程中全部的文件读取,更确切说,全部的字符串。如果字符串是明文写在脚本中,如“sound\\aaa.mp3”,那么火龙会认为这可能是个文件,然后顺藤摸瓜找到它。但如果写成“sound\\” + “aaa.mp” + I2S(3)等甚至加上存取哈希表动作,火龙或任何软件也无法完全预知。这种不可预测是理论级的,即“图灵机无法预测另一台图灵机的全部可能状态”,等价于著名的“停机问题”,而停机问题是“理论不可计算”的。所以在游戏中虽然能正常听到音乐(或看到特效等),但火龙却无法提前知道这个文件的存在。 样例的图中正是这样,隐藏了一个2m+的mp3文件,但火龙却只能读出一大打war3map.xxx。 然后这种方法也能隐藏其它文件,但无法隐藏在物编中使用到的文件(如被某单位使用的导入模型)、地图必备文件(如j)和覆盖原路径文件(如替换的载入图片)。 3.hash扫描式。但是还没完,还有一种方式,某些软件绕过mpq前面的哈希索引表,直接扫描后面的文件,这样虽然不能知道文件名,但能得到完整的文件列表(再怎么说文件也是封在mpq里的吧,把mpq整个扫一遍总能发现)。例子是新版mpqeditor,样例图和某人提供的火影图都能打开,能看到一堆没有文件名的文件,其中就有隐藏的mp3,改成mp3扩展名就能正常播放。这种方式应该没什么弊端(除了得不到正确文件名),如果和火龙结合,用上述方法隐藏的文件也能以“未知名文件”的形式显示出来,其他文件则完美显示。 所以mpq这种文件格式终究逃不过被拆的厄运,想完美隐藏文件果然是不可能的事情。全文完。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值