列表

详情


NC20465. [ZJOI2006]GAMEZ游戏排名系统

描述

GameZ为他们最新推出的游戏开通了一个网站。世界各地的玩家都可以将自己的游戏得分上传到网站上。这样就可以看到自己在世界上的排名。得分越高,排名就越靠前。当两个玩家的名次相同时,先上传记录者优先。
由于新游戏的火爆,网站服务器已经难堪重负。为此GameZ雇用了你来帮他们重新开发一套新的核心。
排名系统通常要应付三种请求:上传一条新的得分记录、查询某个玩家的当前排名以及返回某个区段内的排名记录。当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除。
为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录。

输入描述

第一行是一个整数n(n ≥ 10)表示请求总数目。
接下来n行每行包含了一个请求。请求的具体格式如下:
+Name Score 上传最新得分记录。Name表示玩家名字,由大写英文字母组成,不超过10个字符。Score为最多8位的正整数。
?Name 查询玩家排名。该玩家的得分记录必定已经在前面上传。
?Index 返回自第Index名开始的最多10名玩家名字。Index必定合法,即不小于1,也不大于当前有记录的玩家总数。
输入文件总大小不超过2M。
NOTE:用C++的fstream读大规模数据的效率较低

输出描述

对于每条查询请求,输出相应结果。
对于?Name格式的请求,应输出一个整数表示该玩家当前的排名。
对于?Index格式的请求,应在一行中依次输出从第Index名开始的最多10名玩家姓名,用一个空格分隔。

示例1

输入:

20
+ADAM 1000000
+BOB 1000000
+TOM 2000000
+CATHY 10000000
?TOM
?1
+DAM 100000
+BOB 1200000
+ADAM 900000
+FRANK 12340000
+LEO 9000000
+KAINE 9000000
+GRACE 8000000
+WALT 9000000
+SANDY 8000000
+MICK 9000000
+JACK 7320000
?2
?5
?KAINE

输出:

2
CATHY TOM ADAM BOB
CATHY LEO KAINE WALT MICK GRACE SANDY JACK TOM BOB
WALT MICK GRACE SANDY JACK TOM BOB ADAM DAM
4

说明:

20 +ADAM 1000000 加入ADAM的得分记录

+BOB 1000000 加入BOB的得分记录

+TOM 2000000 加入TOM的得分记录

+CATHY 10000000 加入CATHY的得分记录

?TOM 输出TOM目前排名

?1 目前有记录的玩家总数为4,因此应输出第1名到第4名。

+DAM 100000 加入DAM的得分记录

+BOB 1200000 更新BOB的得分记录

+ADAM 900000 更新ADAM的得分记录(即使比原来的差)

+FRANK 12340000 加入FRANK的得分记录

+LEO 9000000 加入LEO的得分记录

+KAINE 9000000 加入KAINE的得分记录

+GRACE 8000000 加入GRACE的得分记录

+WALT 9000000 加入WALT的得分记录

+SANDY 8000000 加入SANDY的得分记录

+MICK 9000000 加入MICK的得分记录

+JACK 7320000 加入JACK的得分记录

?2 目前有记录的玩家总数为12,因此应输出第2名到第11名。

?5 输出第5名到第13名。

?KAINE 输出KAINE的排名

输入文件总大小不超过 2M。

NOTE:用 C++ 的 fstream 读大规模数据的效率较低

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 428ms, 内存消耗: 42132K, 提交时间: 2020-01-21 19:58:47

#include <bits/stdc++.h>
#include <bits/extc++.h>

using namespace std;
using namespace __gnu_pbds;

constexpr int MAXN = 30;
constexpr int MAX_LIST = 10;
char instruction[MAXN];

struct Node {
    int val{};
    int id{};
    string name;

    Node() = default;

    Node(int val, int id, string name) : val(val), id(id),
                                         name(std::move(name)) {}

    bool operator>(const Node &other) const {
        if (val == other.val) {
            return (id < other.id);
        }
        return (val > other.val);
    }
};

tree<Node, null_type, greater<>, rb_tree_tag,
        tree_order_statistics_node_update> Rbtree;
unordered_map<string, Node> Hashmap;

int main() {

    int n;
    int val;
    string temp_str;
    int rank;
    int counter;
    bool firstItem;
    scanf("%d", &n);
    for (int kase = 0; kase < n; ++kase) {
        scanf("%s", instruction);
        if (instruction[0] == '+') {
            // Example: +FRANK 12340000
            scanf("%d", &val);
            temp_str = "";
            for (int i = 1; instruction[i] != '\0'; ++i) {
                temp_str.push_back(instruction[i]);
            }

            if (Hashmap.find(temp_str) == Hashmap.end()) {
                Hashmap[temp_str].name = temp_str;
                Hashmap[temp_str].val = val;
                Hashmap[temp_str].id = kase;
                Rbtree.insert(Node(val, kase, temp_str));
            } else {
                Rbtree.erase(Node(Hashmap[temp_str].val, Hashmap[temp_str].id,
                                  temp_str));
                Hashmap[temp_str].val = val;
                Hashmap[temp_str].id = kase;
                Rbtree.insert(Node(val, kase, temp_str));
            }

        } else if (isdigit(instruction[1])) {
            // Example: ?2
            temp_str = "";
            for (int i = 1; instruction[i] != '\0'; ++i) {
                temp_str.push_back(instruction[i]);
            }
            rank = stoi(temp_str) - 1;
            firstItem = true;
            auto iter = Rbtree.find_by_order(rank);
            counter = 0;
            while (iter != Rbtree.end()) {
                if (counter == MAX_LIST) {
                    break;
                }
                if (firstItem) {
                    firstItem = false;
                } else {
                    printf(" ");
                }
                printf("%s", iter->name.c_str());
                ++counter;
                ++iter;
            }
            if (!firstItem) {
                printf("\n");
            }
        } else {
            // Example: ?KAINE
            temp_str = "";
            for (int i = 1; instruction[i] != '\0'; ++i) {
                temp_str.push_back(instruction[i]);
            }
            printf("%lu\n", Rbtree.order_of_key(
                    Node(Hashmap[temp_str].val, Hashmap[temp_str].id,
                         temp_str)) + 1);
        }
    }

    return 0;
}

C++ 解法, 执行用时: 467ms, 内存消耗: 46836K, 提交时间: 2022-04-16 23:06:23

#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<vector>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#include<cctype>
#include<list>
#include<stack>
#define ri register int
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
const int inf=0x3f3f3f3f;
const double pi=acos(-1.0);
const double eps=1e-10;
const int M=5e5+100;
int n,m,val[M],cnt,tot;
char c;
string s,ss[M];
map<string,int>mp;
struct Node
{
	int v,id;
	bool operator<(const Node&x) const
	{
		if(v==x.v) return id<x.id;
		return v>x.v;
	}
};
tree<Node,null_type,less<Node>,rb_tree_tag,tree_order_statistics_node_update>T;
inline int read(){
	int x=0,k=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') k=-1;ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
	return x*k;
}
inline void write(int x){
	if(x<0) x=~x+1,putchar('-');
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
inline int GCD(int a,int b){return b?GCD(b,a%b):a;}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int tem,x;
	cin>>n;
	while(n--)
	{
		cin>>c>>s;
		if(c=='+')
		{
			if(mp[s])
			{
				tem=mp[s];
				T.erase(Node{val[tem],tem});
				tot--;
			}
			mp[s]=++cnt;
			cin>>val[cnt];
			T.insert(Node{val[cnt],cnt});
			tot++;
			ss[cnt]=s;
		}
		else if(c=='?'&&!isdigit(s[0]))
		{
			x=mp[s];
			cout<<T.order_of_key(Node{val[x],x})+1<<endl;
		}
		else
		{
			x=0;
			for(int i=0;i<s.size();i++) x=x*10+s[i]-'0';
			tem=min(tot,x+9);
			for(int i=x-1;i<=tem-1;i++) cout<<ss[T.find_by_order(i)->id]<<' ';cout<<endl;
		}
	}
	return 0;
}

上一题