题解 | #指纹锁#
指纹锁
https://ac.nowcoder.com/acm/problem/17508
链接:https://ac.nowcoder.com/acm/problem/17508
来源:牛客网
思路:set函数+重载运算符
来源:牛客网
题目描述
HA实验有一套非常严密的安全保障体系,在HA实验基地的大门,有一个指纹锁。
该指纹锁的加密算***把一个指纹转化为一个不超过1e7的数字,两个指纹数值之差越小,就说明两个指纹越相似,当两个指纹的数值差≤k时,这两个指纹的持有者会被系统判定为同一个人。
现在有3种操作,共m个,
操作1:add x,表示为指纹锁录入一个指纹,该指纹对应的数字为x,如果系统内有一个与x相差≤k的指纹,则系统会忽略这次添加操作
操作2:del x,表示删除指纹锁中的指纹x,若指纹锁中多个与x相差≤k的指纹,则全部删除,若指纹锁中没有指纹x,则可以忽略该操作,
操作3:query x,表示有一个持有指纹x的人试图打开指纹锁,你需要设计一个判断程序,返回该人是否可以打开指纹锁(只要x与存入的任何一个指纹相差≤k即可打开锁)。
初始状态,指纹锁中没有任何指纹。
现在有3种操作,共m个,
操作1:add x,表示为指纹锁录入一个指纹,该指纹对应的数字为x,如果系统内有一个与x相差≤k的指纹,则系统会忽略这次添加操作
操作2:del x,表示删除指纹锁中的指纹x,若指纹锁中多个与x相差≤k的指纹,则全部删除,若指纹锁中没有指纹x,则可以忽略该操作,
操作3:query x,表示有一个持有指纹x的人试图打开指纹锁,你需要设计一个判断程序,返回该人是否可以打开指纹锁(只要x与存入的任何一个指纹相差≤k即可打开锁)。
初始状态,指纹锁中没有任何指纹。
输入描述:
第一行有2个正整数m,k。 接下来m行,每行描述一种操作:add x,del x或query x。
输出描述:
对于每个query操作,输出一行,包含一个单词“Yes”或“No”,表示该人是否可以打开指纹锁。
注:set函数内元素如果不是结构体,可以重载()运算符;如果是结构体,可以讲比较函数写在结构体之内,重载<运算符
本题使用重载()运算符,实现判断是否需要插入,一次性若干个删除,以及查询范围内是否存在相关元素的三个操作
add x对应set里的insert()函数
delete x对应set里的erase()函数
query x对应set里的find()函数,当查找不到时,其值=end()
本题主要是模拟一个过程,不需要考虑其他算法
代码如下
#include<stdio.h>
#include<bits/stdc++.h>
#pragma GCC optimize(2) //开启O2优化,虽然似乎只提升了10~20ms
using namespace std;
char s[10];
int m,k,num;
struct comp{
bool operator () (const int &a,const int &b)const{ //不是结构体,重载()运算符
if(abs(a-b)<=k) return false; //return false表明现在输入的数与之前输入的数一样,不加入set里
else return a<b; //表明输入的数与之前的数不相同,就按照从小到大进行排序
}
}; //这个重载运算符在insert()和erase()中被使用,用来判断是否需要插入,一次性若干个删除,查询范围内是否存在相关元素
set<int,comp>st; //创建一个set函数
inline int read() //快读函数,提升了200ms左右
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9')
x=x*10+ch-'0',ch=getchar();
return x*f;
}
int main() {
m=read();k=read();
//scanf("%d %d",&m,&k);
while(m--) {
scanf("%s",s);
num=read();
//scanf("%d",&num);
if(s[0]=='a') {
st.insert(num); //执行插入操作
}
if(s[0]=='d') {
st.erase(num); //执行删除操作
}
if(s[0]=='q') {
if(st.find(num)==st.end()) printf("No\n"); //执行查找操作,set里的find()函数查找不到此元素时,返回值为end()
else printf("Yes\n");
}
}
return 0;
}
#include<bits/stdc++.h>
#pragma GCC optimize(2) //开启O2优化,虽然似乎只提升了10~20ms
using namespace std;
char s[10];
int m,k,num;
struct comp{
bool operator () (const int &a,const int &b)const{ //不是结构体,重载()运算符
if(abs(a-b)<=k) return false; //return false表明现在输入的数与之前输入的数一样,不加入set里
else return a<b; //表明输入的数与之前的数不相同,就按照从小到大进行排序
}
}; //这个重载运算符在insert()和erase()中被使用,用来判断是否需要插入,一次性若干个删除,查询范围内是否存在相关元素
set<int,comp>st; //创建一个set函数
inline int read() //快读函数,提升了200ms左右
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9')
x=x*10+ch-'0',ch=getchar();
return x*f;
}
int main() {
m=read();k=read();
//scanf("%d %d",&m,&k);
while(m--) {
scanf("%s",s);
num=read();
//scanf("%d",&num);
if(s[0]=='a') {
st.insert(num); //执行插入操作
}
if(s[0]=='d') {
st.erase(num); //执行删除操作
}
if(s[0]=='q') {
if(st.find(num)==st.end()) printf("No\n"); //执行查找操作,set里的find()函数查找不到此元素时,返回值为end()
else printf("Yes\n");
}
}
return 0;
}
算法入门班习题题解&感悟 文章被收录于专栏
这是本人对于算法入门班共十三章习题的题解与个人的一些感悟,本人写题解的目的是对于某些经典的/陌生的/无从下手的/思维方向错误的题目加深印象。 希望自己能够在学习算法的路上走得更远,今天也是努力学习的一天!