P3613 【深基15.例2】寄包柜
思路
数据量大且稀疏,用map
实现
#include<bits/stdc++.h>
using namespace std;
int main()
{
map<int,map<int,int> > a;
int n,m;
cin>>n>>m;
int index,i,j,k;
for(int t=0;t<m;t++)
{
cin>>index;
if(index==1)
{
scanf("%d%d%d",&i,&j,&k);
a[i][j] = k;
}
else
{
scanf("%d%d",&i,&j);
cout<<a[i][j]<<endl;
}
}
return 0;
}
P1449 后缀表达式
思路
用一个栈存操作数,每读入一个操作符,就从栈中弹出两个数,操作后的结果再压入栈
实现
#include<bits/stdc++.h>
using namespace std;
stack<int>q;
string c;
int main()
{
cin>>c;
int a=0,b=0;
int i,j;
for(int k=0;k<c.length();k++)
{
if(c[k]=='@') break;
else if(c[k]=='.'){
q.push(a);
b=0,a=0;
}
else if(c[k]<='9'&&c[k]>='0'){
a=b*10+c[k]-'0';
b=a;
}
else{
if(c[k]=='-') i=q.top(),q.pop(),j=q.top(),q.pop(), q.push(j-i);
if(c[k]=='+') i=q.top(),q.pop(),j=q.top(),q.pop(), q.push(j+i);
if(c[k]=='*') i=q.top(),q.pop(),j=q.top(),q.pop(), q.push(j*i);
if(c[k]=='/') i=q.top(),q.pop(),j=q.top(),q.pop(), q.push(j/i);
}
}
cout<<q.top()<<endl;
}
P1996 约瑟夫问题
思路
用队列实现了一下
实现
#include<bits/stdc++.h>
using namespace std;
queue<int>q;
int n,m,c=0;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
q.push(i);
while(!q.empty())
{
c++;
if(c==m)
{
cout<<q.front()<<" ";
q.pop();
c = 0;
}
else
{
q.push(q.front());
q.pop();
}
}
}
P1540 [NOIP2010 提高组] 机器翻译
思路
队列
实现
#include<bits/stdc++.h>
using namespace std;
queue<int>q;
bool vis[1010];
int n,m,t;
int ans;
int main()
{
cin>>n>>m;
for(int i=0;i<m;i++)
{
scanf("%d",&t);
if(vis[t]) continue;
else
{
if(q.size()>=n)
{
vis[q.front()] = 0;
q.pop();
}
ans++;
q.push(t);
vis[t] = 1;
}
}
cout<<ans;
}
P2058 [NOIP2016 普及组] 海港
思路
用一个队列,里面按人头存这个人的时间和国籍。维护一个数组来记录在当前时间24小时之内每个国籍的人数。维护ans即可
实现
#include<bits/stdc++.h>
using namespace std;
int n;
int t,m,ind;
int guo[100010];
queue<pair<int,int> > q;
int main()
{
cin>>n;
int ans = 0;
for(int i=0;i<n;i++)
{
scanf("%d %d",&t,&m);
for(int j=0;j<m;j++)
{
scanf("%d",&ind);
q.push(make_pair(t,ind));
if(guo[ind]==0)
{
ans++;
}
guo[ind]++;
}
while(q.front().first<=t-86400)
{
guo[q.front().second]--;
if(guo[q.front().second]==0) ans--;
q.pop();
}
cout<<ans<<endl;
}
}
P1241 括号序列
思路
- 先遍历一遍,用一个bool数组记录每个位置的括号是否匹配。
- 根据bool数组的结果分情况输出即可
实现
#include<bits/stdc++.h>
using namespace std;
int n;
string a;
stack<pair<char,int> > t1;
int main()
{
cin>>a;
n = a.size();
vector<bool> ans(n+1,1);
int i;
for(i=0;i<n;i++)
{
if(a[i]=='(' || a[i]=='[')
{
t1.push(make_pair(a[i],i));
}
else if(a[i]==')')
{
if(t1.empty())
{
ans[i] = 0;
continue;
}
if(t1.top().first=='(')
{
t1.pop();
}
else
{
ans[i] = 0;
}
}
else
{
if(t1.empty())
{
ans[i] = 0;
continue;
}
if(t1.top().first=='[')
{
t1.pop();
}
else
{
ans[i] = 0;
}
}
}
while(!t1.empty())
{
ans[t1.top().second] = 0;
t1.pop();
}
for(int i=0;i<n;i++)
{
if(ans[i])
putchar(a[i]);
else
{
if(a[i]=='(' || a[i]==')')
cout<<"()";
else
cout<<"[]";
}
}
}
P2234 [HNOI2002]营业额统计
思路
用set来维护有序,每次插入时用lower_bound()找到第一个大于等于x的数。
实现
来自洛谷题解区 Okarin
#include<bits/stdc++.h>
using namespace std;
set<int>s;
set<int>::iterator k,a;
int n,x,ans=0;
int main()
{
s.insert(192608170);
s.insert(-192608170);
scanf("%d",&n);
for(register int i=1;i<=n;++i)
{
scanf("%d",&x);
if(s.size()==2)
{
ans+=x;
s.insert(x);
}
else
{
k=s.lower_bound(x);
if(*k!=x)
{
a=k;
a--;
ans+=min(abs(*a-x),abs(*k-x));
s.insert(x);
}
}
}
printf("%d\n",ans);
return 0;
}
欢迎指正-