文章目录
- [1. 英语作⽂(逐个字符输入)](#1. 英语作⽂(逐个字符输入))
- [2. P2234 [HNOI2002] 营业额统计(迭代器加减,越界访问问题)](#2. P2234 [HNOI2002] 营业额统计(迭代器加减,越界访问问题))
- [3. ⽊材仓库](#3. ⽊材仓库)
1. 英语作⽂(逐个字符输入)
https://www.luogu.com.cn/problem/P2786
将 <单词, 含⾦量> 绑定放在 map 中,然后遍历作⽂中的每⼀个字符串,找找 map 中对应单词的含⾦量,累加起来即可。
这道题我反而觉得最难的操作是逐个逐个字符的正确输入
cpp
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int n,p;
LL ret;//存储含金量
map<string,int> mp;//一个存词,一个存含金量
// 判断 ch 是否合法
bool check(char ch)
{
if((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' &&
ch <= 'Z'))
{
return true;
}
else return false;
}
int main()
{
cin>>n>>p;
while(n--)
{
string s;
int t;
cin>>s>>t;
mp[s]=t;
}
//这道题唯一难点 我觉得就是 如何一个一个读取字符,同时要过滤非法字符
string t="";
char ch;
while(scanf("%c",&ch)!=EOF)
{
if(check(ch)) t+=ch;
else//读取非法字符 则开始结算是否要加分并且重置t
{
ret=(ret+mp[t])%p;
t="";
}
}
cout<<ret;
}
2. P2234 [HNOI2002] 营业额统计(迭代器加减,越界访问问题)
https://www.luogu.com.cn/problem/P2234
对于每一个新来的数 (x),找出之前的数中,大于等于 (x) 的最小值 (y),以及小于等于 (x) 的最大值 (z),也就是距离 (x) 最近的一大一小两个数。那么 (y - x) 与 (x - z) 的最小值就是当天的最小波动值。
把所有的最小波动值累加起来即可。
cpp
#include<bits/stdc++.h>
using namespace std;
const int INF=1e7+10;
set<int> st;
int main()
{
int ret,n;
cin>>n;
cin>>ret;
st.insert(ret);
//防止迭代器越界 给个不影响结果的值!
st.insert(-INF);
st.insert(INF);
for(int i=2;i<=n;i++)
{
int x;cin>>x;
auto t1=st.lower_bound(x);
auto t2=t1;
t2--;
ret+=min(abs(x-*t1),abs(x-*t2));
st.insert(x);
}
cout<<ret;
}
3. ⽊材仓库
https://www.luogu.com.cn/problem/P5250
与上题的解法类似,⽤ set 来存储⽊材的信息,每次进货和出货操作都在 set 中进⾏。
cpp
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL INF=1e10+10;
set<LL> st;
int main()
{
st.insert(-INF);
st.insert(INF);
int n;cin>>n;
while(n--)
{
int x,y;
cin>>x>>y;
if(x==1)
{
if(st.count(y)==1)
{
cout<<"Already Exist"<<endl;
}
else
{
st.insert(y);
}
}
else
{
if(st.size()==2)
{
cout<<"Empty"<<endl;
continue;
}
auto t1=st.lower_bound(y);
auto t2=t1;
t2--;
if(abs(y-*t1)<abs(y-*t2))
{
cout<<*t1<<endl;
st.erase(t1);
}
else
{
cout<<*t2<<endl;
st.erase(t2);
}
}
}
}


