首先發出題目鏈接:
鏈接: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;
}