2019牛客暑期多校训练营(第三场)----J-LRU management

首先发出题目链接:
链接:https://ac.nowcoder.com/acm/contest/883/J
来源:牛客网
涉及:unordered_map,链表

点击这里回到2019牛客暑期多校训练营解题—目录贴


题目如下:
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
此题目题解用字典树,但是用STL也可以稳过。考的是基本的增删改查

为了让增删和改更加快速,可以使用链表来实现,使得增删和改的复杂度为O(1),链表中存对应的数字字符串和值。

但是链表用于查找的话复杂度是 O(n),所以还需使用hash表来进行查找需要改链表的哪个位置,hash表可以用STL自带的unordered_map来实现。

用unordered_map,键值则是需要查找的数字字符串,实值则是指向链表中需要修改位置的迭代器。注意如果删除链表内的元素时,还要同时删除map中链表迭代器位置得到字符串。

最后还要注意一下输入输出最好用scanf和printf,如果你要用cin输入,请在代码前加上

ios::sync_with_stdio(false);
cin.tie(0);

要用cout输出的话,请把endl宏定义为’\n’

#define endl "\n"

代码如下:

#include <iostream>
#include <string>
#include <unordered_map>
#include <list> 
using namespace std;
typedef long long ll;
typedef pair<string, int> P;//链表中所存的数据类型
list<P> table;//链表
unordered_map<string, list<P>::iterator> mp;//hash表
int t, q, m, opt, v;//题目所给变量
char s[20];//字符串,由于不用cin输入,所以用字符数组
int main(){
	scanf("%d", &t);
	while(t--){
		scanf("%d%d", &q, &m);
		mp.clear();//清空mp
		table.clear();//清空table
		while(q--){
			scanf("%d%s%d", &opt, s, &v);//输入命令
			if(opt == 0){
				if(mp.find(s) != mp.end()){//查找链表中是否存在这个元素
					printf("%d\n", mp[s]->second);//找到了输出对于值
					table.push_back(*mp[s]);//下面是把这一元素移到末尾的操作
					table.erase(mp[s]);
					mp[s] = --table.end();
				}	
				else{
					printf("%d\n", v);//找不到就输出命令所给的值
					table.push_back(P(s, v));//下面是把这一元素放到链表内操作
					if(table.size() > m){//判断链表内元素是否超过限制
						mp.erase(table.front().first);
						table.pop_front();
					}
					mp[s] = --table.end();
				}
			}
			else{
				if(mp.find(s) == mp.end())	printf("Invalid\n");//在链表内找不到该元素
				else{
					auto it = mp[s];//找到该元素
					if(v == 1 && (*it) == table.back())	printf("Invalid\n");//判断元素是否合法
					else if(v == -1 && (*it) == table.front())	printf("Invalid\n");//判断元素是否合法
					else{//元素合法并输出值
						if(v == 1)	++it;
						if(v == -1)	--it;
						printf("%d\n", it->second);
					}
				}
			}
		}
	}
	return 0;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章