链接:https://ac.nowcoder.com/acm/contest/883/J 来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld

LRU management_#include

LRU management_双端队列_02

LRU management_双端队列_03

LRU management_双端队列_04

输出描述:

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,导致错误!看清题目,看清范围!