2008年浙江大学计算机及软件工程研究生机试真题

http://ac.jobdu.com/problem.php?pid=1029魔咒词典

题目当中每个魔咒用一对括号[  ] 来包含,测试数据在一对括号当中会有空格,这个小问题导致一直是WA,应该首先把一行字符串都读进来,然后在分别提取出魔咒和对应的功能。

方法一:

//使用双map来实现
#include<iostream>
#include<map>
#include<cstdio>
#include<string>
using namespace std;

map<string,string>map_magic,map_funtion;
int main(void)
{
	int n,k;
	string str1,str2,str,temp_str;
	map_magic.clear();
	map_funtion.clear();
	while(getline(cin,temp_str))
	{
		if(temp_str=="@END@")
			break;
		k=temp_str.find("]");
		str1=temp_str.substr(0,k+1);
		str2=temp_str.substr(k+2,temp_str.size()-k-2);
		map_magic[str1]=str2;
		map_funtion[str2]=str1;
	}
	scanf("%d",&n);
	getchar();
	while(n--)
	{
		getline(cin,str);
		if(str[0]=='[')
		{
			if(map_magic.count(str))
				cout<<map_magic[str]<<endl;    //由魔咒来选择功能
			else
				cout<<"what?"<<endl;
		}
		else
		{
			if(map_funtion.count(str))
			{
				temp_str=map_funtion[str];     //由功能来选择魔咒
				cout<<temp_str.substr(1,temp_str.size()-2)<<endl;
			}
			else
				cout<<"what?"<<endl;
		}
	}
	return 0;
}

方法二:

//字符串哈希的时间最快,只需要10 MS
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

#define N 100100
#define M 100100

const char *end = "@END@";
char word[N][25], expr[N][85];
int magic[M], funtion[M];

unsigned int bkdrHash(char *str)
{
	unsigned int seed = 131;
	unsigned int hash = 0;
	while(*str)
	{
		hash = hash * seed + *str++;
	}
	return (hash & 0x7FFFFFFF) % M;
}

int setPos(int idx, int arr[])
{
	int i = 1;
	while(arr[idx])   //哈希地址冲突的时候
	{
		idx = (idx + i * i) % M;    //处理哈希冲突的方法,二次探测再散列
		i++;
	}
	return idx;
}
int getPos(int idx, int arr[], int type, char *str)
{
	int i = 1, k = 0;
	while(arr[idx])
	{
		if(type == 0 && strcmp(word[arr[idx]], str) == 0)
		{
			k = magic[idx];   //找到魔咒在字典中的位置
			break;
		}
		else if(type && strcmp(expr[arr[idx]], str) == 0)
		{
			k = funtion[idx];   //找到功能在字典中的位置
			break;
		}
		else
		{
			idx = (idx + i * i) % M;
			i++;
		}
	}
	return k;
}
int main(void)
{
	char str[128];
	int i, j, k, n;
	k = 1;
	memset(magic, 0, sizeof(magic));
	memset(funtion, 0, sizeof(funtion));
	while(gets(str))
	{
		if(strcmp(str, end) == 0)
			break;
		for(i=0;str[i]!= ']';i++)
			word[k][i]=str[i];  //保存魔咒
		word[k][i]=str[i];
		i++;
		word[k][i++]='\0';

		j = setPos(bkdrHash(word[k]), magic);
		magic[j] = k;

		j = 0;
		for(;str[i]!='\0';i++)
			expr[k][j++]=str[i];     //保存功能
		expr[k][j]='\0';
		j = setPos(bkdrHash(expr[k]), funtion);
		funtion[j] = k;
		k++;
	}
	scanf("%d", &n);
	getchar();
	while(n--)
	{
		gets(str);
		if(str[0] == '[')
		{
			j = getPos(bkdrHash(str), magic, 0, str);
			if(j)    //查询成功
				puts(expr[j]);
			else     //查询失败
				printf("what?\n");
		}
		else
		{
			j = getPos(bkdrHash(str), funtion, 1, str);
			if(j)
			{
				k = strlen(word[j]);
				for(i = 1; i < k-1; i++)
					printf("%c", word[j][i]);
				printf("\n");
			}
			else
				printf("what?\n");
		}
	}
	return 0;
}
方法三:

//二分查找
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<string>
using namespace std;

struct Word
{
	string magic;
	string funtion;  
}word;

vector<Word> dic1,dic2;

int my_binary_search(int low, int high,string key,int i)
{
	int mid;
	if(i==1)        //查找魔咒
	{
		while(low<=high)
		{
			mid=(low+high)>>1;
			if(key<dic1[mid].magic)
				high=mid-1;
			else if(key==dic1[mid].magic)
				return mid;
			else
				low=mid+1;
		}
	}
	else if(i==2)        //查找功能
	{
		while(low<=high)
		{
			mid=(low+high)>>1;
			if(key<dic2[mid].funtion)
				high=mid-1;
			else if(key==dic2[mid].funtion)
				return mid;
			else
				low=mid+1;
		}
	}
	return -1;  //查找失败
}

bool cmp1(const Word &a,const Word &b)
{
	return a.magic<b.magic;
}
bool cmp2(const Word &a,const Word &b)
{
	return a.funtion<b.funtion;
}

int main(void)
{
	int n,k;
	string str,temp_str;
	while(getline(cin,temp_str))
	{
		if(temp_str=="@END@")
			break;
		k=temp_str.find("]");
		word.magic=temp_str.substr(0,k+1);
		word.funtion=temp_str.substr(k+2,temp_str.size()-k-2);
		dic1.push_back(word);
		dic2.push_back(word);
	}

	sort(dic1.begin(), dic1.end(), cmp1);      //按照魔咒的字典序进行排序
	sort(dic2.begin(), dic2.end(), cmp2);      //按照功能的字典序进行排序

	scanf("%d",&n);
	getchar();
	vector<Word>::iterator iter;    //vector的迭代器
	while(n--)
	{
		getline(cin,str);
		if(str[0]=='[')     //由魔咒来选择功能
		{
			k=my_binary_search(0, dic1.size()-1,str,1);
			if(k!=-1)
				cout<<dic1[k].funtion<<endl;
			else
				cout<<"what?"<<endl;
		}
		else
		{
			k=my_binary_search(0, dic2.size()-1 ,str,2);
			if(k!=-1)
			{
				temp_str=dic2[k].magic;
				cout<<temp_str.substr(1,temp_str.size()-2)<<endl;
			}
			else
				cout<<"what?"<<endl;
		}
	}
	return 0;
}

方法四: (可能会导致超时)

//使用一个map来实现,反过来用迭代器查询
#include<iostream>
#include<map>
#include<cstdio>
#include<string>
using namespace std;

map<string,string>map_magic;
int main(void)
{
	int n,k;
	string str1,str2,str,temp_str;
	map_magic.clear();
	while(getline(cin,temp_str))
	{
		if(temp_str=="@END@")
			break;
		k=temp_str.find("]");
		str1=temp_str.substr(0,k+1);
		str2=temp_str.substr(k+2,temp_str.size()-k-2);
		map_magic[str1]=str2;
	}
	scanf("%d",&n);
	getchar();
	map<string,string>::iterator iter;    //map的迭代器
	while(n--)
	{
		getline(cin,str);
		if(str[0]=='[')
		{
			if(map_magic.count(str))
				cout<<map_magic[str]<<endl;    //由魔咒来选择功能
			else
				cout<<"what?"<<endl;
		}
		else
		{
			for(iter=map_magic.begin();iter!=map_magic.end();iter++)
			{
				if((*iter).second==str)
				{
					temp_str=(*iter).first;
					cout<<temp_str.substr(1,temp_str.size()-2)<<endl;
					break;
				}
			}
			if(iter==map_magic.end())
				cout<<"what?"<<endl;
		}
	}
	return 0;
}

http://ac.jobdu.com/problem.php?id=1030  毕业bg

/*
题目实质是01背包问题,不过加了几方面的限制
将bg当作物品,离开时间当作重量,快乐度当作价值,则与01背包不同的是物品放入的顺序是有先后顺序的
所以需要排序
*/
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
#include<memory.h>

struct Node
{
	int happy;
	int last;
	int time;
}node[31];

bool cmp(const Node &a,const Node &b)
{
	return a.time<b.time;
}

int dp[1000];

int ZeroOnePack(int n)
{
	int i,j,max=-1,p;
	memset(dp,0,sizeof(dp));

	for(i=0;i<n;i++)   //动态规划
	{
		if(node[i].time>max)
			max=node[i].time;
		for(j=node[i].time;j>=node[i].last;j--)   //j表示背包的大小,从最后离开的时间到持续时间
			dp[j] = dp[j]>dp[j-node[i].last]+node[i].happy? dp[j]:dp[j-node[i].last]+node[i].happy;
	}
	p=-1;
	for(i=1;i<=max;i++)
	{
		if(dp[i]>p)
			p=dp[i];
	}
	return p;
}

int main(void)
{
	int i,n;
    while(scanf("%d",&n)!=EOF)
    {
		if(n<0)
			break;
		for(i=0;i<n;i++)
			scanf("%d %d %d",&node[i].happy,&node[i].last,&node[i].time);
		sort(node,node+n,cmp);   //按最后离开的时间从小到大排序
		printf("%d\n",ZeroOnePack(n));
    }
    return 0;
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值