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;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章