洛谷题单【数据结构1-1】线性表

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;
}

欢迎指正-

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值