L SSH
题目大意:
SSH服务,验证用户身份
给你 m 个密钥对,每个密钥对包含一个公钥和一个私钥
n 台主机,每台主机都有一个唯一的 IPv4 地址和一定数量的用户,用户以用户名区分,同一台主机上的用户不能重名。每个用户有仅属于自己的一些公钥
q 次查询,每次查询给出一个用户名,一个 IPv4 地址以及此次登录使用的私钥,要求你判断该 IPv4 地址对应的主机上的用户,是否拥有这个私钥对应的公钥
赛时主要是一直想用map嵌套map的方式实现,但是嵌套的东西有点多,而且不太会遍历,赛后看到了用结构体储存的写法
思路:
模拟题且数据范围比较小,先将每个公钥和私钥用map配对,再将每个主机的ipv4地址和用户以及用户含有的公钥存入结构体,询问时,通过遍历ipv4地址中用户名进行查询,找到对应用户后,将该用户含有公钥对应私钥与需要查询私钥配对即可
Solved:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
struct op
{
string ip;
string user[20];
int userI;
string pub[20][20];
int pubI[20];
}p[110];
void solve()
{
map<string,string> mp;
int m,n,q;cin>>m>>n>>q;
while(m--){
string s1,s2;cin>>s1>>s2;
mp[s1]=s2;
}
for(int i=1;i<=n;i++){
cin>>p[i].ip;
cin>>p[i].userI;
for(int j=1;j<=p[i].userI;j++){
cin>>p[i].user[j];
cin>>p[i].pubI[j];
for(int k=1;k<=p[i].pubI[j];k++){
cin>>p[i].pub[j][k];
}
}
}
while(q--){
string Ip,User,pri;
cin>>User>>Ip>>pri;
int flag=0;
for(int i=1;i<=n;i++){
if(p[i].ip==Ip ){
for(int j=1;j<=p[i].userI;j++){
if(p[i].user[j]==User){
for(int k=1;k<=p[i].pubI[j];k++){
if(mp[p[i].pub[j][k]]==pri){
flag=1;
// break;
}
}
}
// if(flag==1){
// break;
// }
}
}
// if(flag==1){
// break;
// }
}
if(flag==1){
cout<<"Yes"<<endl;
}else{
cout<<"No"<<endl;
}
}
}
signed main()
{
std::ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t=1;
// cin>>t;
while(t--){
solve();
}
return 0;
}
K 暴食之史莱姆
题目大意:
有n个史莱姆排成一条线,1~n,第i只体积为ai,当且仅当他的体积大于等于邻居时,可以吃掉邻居,体积变为邻居的体积,求每个史莱姆最多可以吃多少个同伴
思路:
首先可以想到如果第x个史莱姆
-
吃左边最多的同伴就是x左边单调递减的邻居,
-
吃右边最多的同伴就是x右边单调递减的邻居,
如果想要吃的最多,由于左右两边都是求得单调递减的,所以x必然有一种方式能将左右两边邻居都吃掉,该题不输出怎么吃,因此,可以使用单调栈求一下x左右两边的单调递减区间
Solved:
signed main()
{
int n;cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
stack<int> lst,rst;
lst.push(a[1]);
for(int i=2;i<=n;i++){
while(!lst.empty()&&a[i]<lst.top()){
lst.pop();
}
lst.push(a[i]);
l[i]=lst.size()-1;
}
rst.push(a[n]);
for(int i=n-1;i>=1;i--){
while(!rst.empty()&&a[i]<rst.top()){
rst.pop();
}
rst.push(a[i]);
r[i]=rst.size()-1;
}
for(int i=1;i<=n;i++){
cout<<l[i]+r[i]<<" ";
}
return 0;
}