牛客-[NOIP2017]图书管理员——字典树or排序取模
Posted C+++++++++++++++++++
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客-[NOIP2017]图书管理员——字典树or排序取模相关的知识,希望对你有一定的参考价值。
题目
题目详解
这题也有两种做法,而且都不慢。
- 改造字典树的做法:
我们用书的编号建立字典树,每次插入一段编号,从尾部开始分解,进行字典树的建立,字典树的每一个结点存下这个尾部对应的最大前缀即可。建立好字典树后,查找过程也只需要查查一下即可得到结果。时间复杂度插入为O(n),查询为O(n),这里的n指的都是编号的长度。实际上此题编号长度不会超过9,所以完全可以视作是常数级别的复杂度。所以整个插入和查询过程可以看作是O(n)和O(m)的复杂度,n表示要插入的编号个数,m表示要查询的个数。 - 直接排序强行枚举(本题的正统解法):
由于本题的数据量都不超过一个int,所以把图书编号存下来排好序,而正好输入的数据有所需图书编号的位数,所以直接可以通过取模判断图书编号是否以该所需编号结尾!而得到的第一个结果正好就算最小值了。
解题代码
法一:字典树
#include<bits/stdc++.h>
using namespace std;
struct node
int remain_minV;//TODO 每个结点存下到了这个位置之后的最小剩余量。
node* next[10];
node()
remain_minV = INT_MAX;
memset(next,0,sizeof(next));
node(int val)
remain_minV = val;
memset(next,0,sizeof(next));
void update(int val)
remain_minV = min(remain_minV,val);
;
//TODO 字典树实现
struct Trie
node root;
void add(int val)
int data = val;
node* cur = &root;
while (data)
int c = data%10,pre = data/10;
if(!cur->next[c])
cur->next[c] = new node(pre);
else
cur->next[c]->update(pre);
cur = cur->next[c];
data/=10;
int find(int src)
int data = src;
node* cur = &root;
bool f = true;
while (data)
int c = data%10;
if(cur->next[c]==0)
f = false;
break;
cur = cur->next[c];
data /= 10;
if(!f)return -1;
string sum = to_string(cur->remain_minV)+to_string(src);
return atoi(sum.c_str());
;
//TODO 具体的使用,就只需要调用我实现的数据结构即可
int main()
ios::sync_with_stdio(false);
int p,q;cin>>p>>q;
int book_code,need_code;
Trie check;
while (p--)
cin>>book_code;
check.add(book_code);
while (q--)
int t;cin>>t>>need_code;
cout<<check.find(need_code)<<'\\n';
return 0;
法二:排序+取模判断
#include<cstdio>
#include<algorithm>
#include<cmath>
const int N=1000;
int n,m,a[N+5];
int mod,reader;
bool f;
int readint()
int x=0;char c=getchar();
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9')x=x*10+c-'0';c=getchar();
return x;
int main()
n=readint();m=readint();
for(int i=1;i<=n;i++)
a[i]=readint();
std::sort(a+1,a+n+1);//TODO 排序
for(int i=1;i<=m;i++)
mod=(int)pow(10,readint());
reader=readint();
f=1;
for(int i=1;i<=n;i++)
if(a[i]%mod==reader)//TODO 取模判断
printf("%d\\n",a[i]);
f=0;
break;
if(f) printf("-1\\n");
return 0;
以上是关于牛客-[NOIP2017]图书管理员——字典树or排序取模的主要内容,如果未能解决你的问题,请参考以下文章