HDOJ-1880 魔咒词典

魔咒词典

Time Limit: 8000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 15546    Accepted Submission(s): 3705


Problem Description
哈利波特在魔法学校的必修课之一就是学习魔咒。据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你的帮助。

给你一部魔咒词典。当哈利听到一个魔咒时,你的程序必须告诉他那个魔咒的功能;当哈利需要某个功能但不知道该用什么魔咒时,你的程序要替他找到相应的魔咒。如果他要的魔咒不在词典中,就输出“what?”
 

Input
首先列出词典中不超过100000条不同的魔咒词条,每条格式为:

[魔咒] 对应功能

其中“魔咒”和“对应功能”分别为长度不超过20和80的字符串,字符串中保证不包含字符“[”和“]”,且“]”和后面的字符串之间有且仅有一个空格。词典最后一行以“@END@”结束,这一行不属于词典中的词条。
词典之后的一行包含正整数N(<=1000),随后是N个测试用例。每个测试用例占一行,或者给出“[魔咒]”,或者给出“对应功能”。
 

Output
每个测试用例的输出占一行,输出魔咒对应的功能,或者功能对应的魔咒。如果魔咒不在词典中,就输出“what?”
 

Sample Input
 
 
[expelliarmus] the disarming charm [rictusempra] send a jet of silver light to hit the enemy [tarantallegra] control the movement of one's legs [serpensortia] shoot a snake out of the end of one's wand [lumos] light the wand [obliviate] the memory charm [expecto patronum] send a Patronus to the dementors [accio] the summoning charm @END@ 4 [lumos] the summoning charm [arha] take me to the sky
 

Sample Output
 
 
light the wand accio what? what?
 

Author
ZJU
 

一道一看就知道是用map+string的题,于是上去MTL。。。。坑。。。神坑。。。天坑快哭了快哭了快哭了

双手奉上超时代码/捂脸/捂脸/捂脸↓↓↓

#include <cstdio>
#include <iostream>
#include <cstring>
#include <map>
using namespace std;

string text;
string key;
string value;

map<string,string> s;

int main() {
//	freopen( "input.txt","r",stdin );
	int t,i;
	bool flag;
	while( getline( cin,text ) ) {
		if( text == "@END@" )
			break;
		int l = text.find('[');
		int r = text.find(']');
		//第r位是右括号
		key = text.substr( l+1,r-1 );
		//第r+1位是空格,第r+2为才是咒语内容开始,直到长度-1
		value = text.substr( r+2,text.size()-1 );
//		cout << key << "111" << value << endl;
		//咒语存为索引
		s[key] = value;
		//内容存为索引
		s[value] = key;
		key.clear();
		value.clear();
	}
	scanf( "%d",&t );
	//吸收换行 
	getchar();
	while( t-- ){
		flag = false;
		getline( cin,key );
		//是咒语的话就去掉括号
		if( key[0]=='[' ){ 
			key.erase( key.begin() );
			key.erase( key.end()-1 );
		} 
//		cout << key << endl; 
		//找不到就输出what 
		if( s.find(key) == s.end() )
			cout << "what?" << endl;
		else
			cout << s[key] << endl;
		//Em......随时清空是个好习惯 
		key.clear();
	}
	s.clear();
}

然后不得不用字符数组又来了一发。。。好气哦。。。详细代码如下↓↓↓

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#define END "@END@"
using namespace std;

struct Dic {
	char name[22];	//咒语名字 
	char order[82]; //咒语内容 
} d[2][100010];//双份的 

char c[105];
char k[105];
int cnt;

//咒语名从小到大排序 
int cmp1( const void *a , const void *b ) {
	struct Dic *A = (Dic*) a;
	struct Dic *B = (Dic*) b;
	return strcmp( A->name,B->name );
}

//咒语内容从小到大排序 
int cmp2( const void *a , const void *b ) {
	struct Dic *A = (Dic*) a;
	struct Dic *B = (Dic*) b;
	return strcmp( A->order,B->order );
}

//二分查找 
void binSearch( char *v , int i ) {
	int l = 0;
	int r = cnt-1;
	int mid;
	if( i==0 ) {
		while( l<=r ) {
			mid = ( l+r )/2;
			if( strcmp( v,d[i][mid].name )>0 )
				l = mid + 1;
			else if( strcmp( v,d[i][mid].name )<0 )
				r = mid - 1;
			else{
				//找到直接输出 
				printf( "%s\n",d[i][mid].order );
				return ;
			} 
		}
	} else {
		while( l<=r ) {
			mid = ( l+r )/2;
			if( strcmp( v,d[i][mid].order )>0 )
				l = mid + 1;
			else if( strcmp( v,d[i][mid].order )<0 )
				r = mid - 1;
			else{
				//找到直接输出 
				printf( "%s\n",d[i][mid].name );
				return ; 
			} 
		}
	}
	//找不到输出what 
	printf( "what?\n" );
}

int main() {
//	freopen( "input.txt","r",stdin );
	int i,j,t,pos;
	cnt = 0;
	while( gets(c) && strcmp( c,END )!=0 ) {
		//忽略'[',从第1位开始 
		for( i=1 , j=0; c[i]!=']' ; i++ , j++ )
			d[0][cnt].name[j] = c[i];
		//字符串终止,一会还要比较的 
		d[0][cnt].name[j] = '\0';
		//从']'到内容的第一个字符 
		i += 2;
		//取内容 
		for( j=0 ; c[i] ; i++,j++ )
			d[0][cnt].order[j] = c[i];
		d[0][cnt].order[j] = '\0';
		d[1][cnt] = d[0][cnt];
		//别忘了计数器+1 
		cnt++;
	}
	//双重快排,一个按名字,一个按内容 
	qsort( d[0],cnt,sizeof(Dic),cmp1 );
	qsort( d[1],cnt,sizeof(Dic),cmp2 );
	scanf( "%d",&t );
	//吸收调皮的换行 
	getchar();
	while( t-- ) {
		gets(c);
		//处理一下咒语的括号 
		if( c[0]=='[' ) {
			for( i=1,j=0 ; c[i]!=']' ; i++,j++ )
				k[j] = c[i];
			k[j] = '\0';
			//二分查找 
			binSearch( k,0 );
		} else {
			binSearch( c,1 );
		}
	}
}

对了,如果map有什么好方法记得留言告诉我哦ヾ(✿゚▽゚)ノ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值