链接:https://ac.nowcoder.com/acm/contest/883/J 来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
输出描述:
For each case, print the result of each operation in a line as defined in the input section of the statement.
示例1
输入
复制
1
8 3
0 0101010 1
0 0101011 2
1 0101010 1
0 1100000 3
0 0101011 -1
0 1111111 4
1 0101011 -1
1 0101010 0
输出
复制
1
2
2
3
2
4
3
Invalid
思路:双端队列+哈希表
对应的,双端队列中存的节点node包含 name 和 value
哈希表 通过 name 和 节点的指针 node* 的映射,能够快速通过名字查找到对应的节点指针,
得到指针后,我们可以快速得得到 name 和 value
双端队列是因为能够快速得 删除和插入,正好是题目所需
code:
#include <iostream>
#include<cstring>
#include<map>
#include<cstdio>
using namespace std;
struct Node{
string name;
int value;
Node *pre;
Node *next;
Node(){};
Node(string name,int value):name(name),value(value){pre = NULL;next=NULL;};
};
Node *head;
Node *tail;
int capacity;
int size;
map<string,Node*> map_;
void add(Node *node){
Node *oiginal = head->next;
head->next = node;
node->pre = head;
node->next = oiginal;
oiginal->pre = node;
}
void del(Node *node){
Node *preNode = node->pre;
Node *nextNode = node->next;
preNode->next = nextNode;
nextNode->pre = preNode;
node->pre = NULL;
node->next = NULL;
// delete node;
}
void init(int cap){
map_.clear();
head = new Node();
tail = new Node();
head->next = tail;
tail->pre = head;
capacity = cap;
size = 0;
}
int get(string name){
if(map_.find(name)==map_.end())return -1111;
Node *node = map_[name];
del(node);
add(node);
return node->value;
}
Node* getcount(Node *node,int b){
if(b== -1){
if(node->next == tail){
node = NULL;
}else{
node = node->next;
}
}else if(b == 1){
if(node->pre == head){
node = NULL;
}else{
node = node->pre;
}
}
return node;
}
void pout_node(){
Node *start = head->next;
while(start!=tail){
printf("name:%s value:%d\n",start->name.c_str(),start->value);
start = start->next;
}
}
void delete_all(){
Node *start = head;
while(start!=tail){
Node *now = start;
start = start->next;
delete now;
}
delete tail;
}
int put(string name,int value){
if(map_.find(name)==map_.end()){
if(size<capacity){
size++;
}else{
Node *delnode = tail->pre;
map_.erase(delnode->name);
del(delnode);
// delete delnode;
}
Node *newNode = new Node(name,value);
add(newNode);
map_[name] = newNode;
return value;
}
Node *tmpnode = map_[name];
// tmpnode->value = value;
del(tmpnode);
add(tmpnode);
return tmpnode->value;
}
int T;
int Q,M;
char str[11];
int main() {
scanf("%d",&T);
while(T--){
scanf("%d%d",&Q,&M);
init(M);
for(int i=0;i<Q;i++){
int a,b;
memset(str,0,sizeof(str));
scanf("%d %s %d",&a,str,&b);
string name(str);
// cout<<name<<endl;
if(a == 0){
int ans = put(name,b);
printf("%d\n",ans);
}else{
if (map_.find(name)==map_.end())
printf("Invalid\n");
else{
Node *temp = map_[name];
temp = getcount(temp,b);
if(temp == NULL)
printf("Invalid\n");
else
printf("%d\n",temp->value);
}
}
// pout_node();
}
// delete_all();
}
return 0;
}
/**
1
8 3
0 0101010 1
0 0101011 2
1 0101010 1
0 1100000 3
0 0101011 -1
0 1111111 4
1 0101011 -1
1 0101010 0
**/
注意点:
1.如果动态得申请和删除节点,会非常耗时,所以这里申请了内存之后,就不要再销毁了,够用,否则会超时!!
2.get函数没写好,写坑了,默认以为 value 的范围为 0-10, 所以就认为没找到节点直接返回-1,导致错误!看清题目,看清范围!