洛谷 P3613 【深基15.例2】寄包柜 详细题解 (vector or map)

该博客详细解析了洛谷P3613题目的解决方案,针对寄包柜问题提出使用vector和map两种数据结构的解法。在避免二维数组导致的空间浪费情况下,通过动态数组vector和一维、二维映射map实现高效查询。文章提供了完整的代码示例,展示如何存储和查询物品位置。

传送门

题目描述

timu
输入
5 4
1 3 10000 114514
1 1 1 1
2 3 10000
2 1 1

输出样例
114514
1

整体思路

这道题首先想到的就是用二维数组,但1e5*1e5必然会导致空间爆炸而且还会有大量的空间浪费。所以就自然而然的想到了动态数组(链表查询次数过多会导致超时)

vector解法

首先介绍vector的解法

  • 构造一个结构体,分别存储i,j,k
struct Node
{
    int s = 0;//柜子使用的次数,一个柜子可能使用很多次
    vector<int> v;//一个柜子的格子数
    vector<int> num;//v格子存放的物品
}a[N];
  • 如何存储i,j,k
cin >> i >> j >> k;
a[i].s++;//存入第i个柜子
a[i].v.push_back(j);//第i个柜子的第j个格子
a[i].num.push_back(k);//存放的物品
  • 如何查询第i个柜子的第j个格子存放的物品
for(int i = a[b].s - 1; i >= 0; i--)
{
     if(a[b].v[i] == c)//找到第b个柜子的第c个格子
     {
           cout << a[b].num[i] << endl;
           break;
     }
}

完整代码

#include <iostream>
#include <vector>
using namespace std;
const int N = 1e5+5;
struct Node
{
    int s = 0;
    vector<int> v;//一个柜子的格子数
    vector<int> num;//v柜子存放的物品
}a[N];
int main()
{
    int n,q;
    cin >> n >> q;
    while(q--)
    {
        int x;
        cin >>x;
        if(x == 1)
        {
            int i,j,k;
            cin >> i >> j >> k;
            a[i].s++;
            a[i].v.push_back(j);
            a[i].num.push_back(k);
        }
        else
        {
            int b,c;
            cin >> b >> c;
            for(int i = a[b].s - 1; i >= 0; i--)
            {
                if(a[b].v[i] == c)
                {
                    cout << a[b].num[i] << endl;
                    break;
                }
            }
        }
    }
    return 0;
}

map一维映射解法

接下来第二种解法就是map一维映射
由于柜子数和格子数都不能超过1e5,所以我们开一个longlong 和int的映射,分别代表柜子数 * 1e5+格子数和存放物品,即 m[i*1e5 + j] = k

#include <iostream>
#include <map>
using namespace std;
typedef long long ll;
const int N = 100000;
map<ll,int> m;
int main()
{
    int n,q;
    cin >> n >> q;
    while(q--)
    {
        int x,i,j;
        cin >> x >> i >> j;
        if(x == 1)
        {
            int k;
            cin >> k;
            m[i * N + j] = k;
        }
        else
        {
            cout << m[i * N + j] << endl;
        }
    }
    return 0;
}

map二维映射

用map开一个二维映射的数组

map<int ,map<int,int> > m;

每次查询输出的值都对应一个二维映射

完整代码

#include <iostream>
#include <map>
using namespace std;
typedef long long ll;
const int N = 100000;
map<int ,map<int,int> > m;
int main()
{
    int n,q;
    cin >> n >> q;
    while(q--)
    {
        int x,i,j;
        cin >> x >> i >> j;
        if(x == 1)
        {
            int k;
            cin >> k;
            m[i][j] = k;
        }
        else
        {
            cout << m[i][j] << endl;
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值