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;
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值