week3-线性表

1.寄包柜

题目描述

超市里有 n(1\le n\le10^5) 个寄包柜。每个寄包柜格子数量不一,第 i 个寄包柜有 a_i(1< a_i<10^5) 个格子,不过我们并不知道各个 a_i的值。对于每个寄包柜,格子编号从 1 开始,一直到 a_i。现在有 q(1 < q<10^5) 次操作:

  • 1 i j k:在第 i 个柜子的第 j 个格子存入物品 k(0< k< 10^9)。当 k=0 时说明清空该格子。
  • 2 i j:查询第 i i i 个柜子的第 j 个格子中的物品是什么,保证查询的柜子有存过东西。

已知超市里共计不会超过 10^7 个寄包格子,a_i 是确定然而未知的,但是保证一定不小于该柜子存物品请求的格子编号的最大值。当然也有可能某些寄包柜中一个格子都没有。

输入格式

第一行 2 个整数 n 和 q,寄包柜个数和询问次数。

接下来 q 个整数,表示一次操作。

输出格式

对于查询操作时,输出答案,以换行隔开。

样例 #1

样例输入 #1

5 4
1 3 10000 118014
1 1 1 1
2 3 10000
2 1 1

样例输出 #1

118014
1

题目中说道要有最多105个寄包柜,在一个寄包柜里又有最多107个格子,这说明我们需要一个非常非常强力的数组,那么非二维数组莫属了(我一开始还想着用二维数组简单AC~),(咳嗽)显然二维数组会MLE,但是我其他方法就是不会该怎么办?这是就用到了map,可以用map创造一个二维映射对应到对应的东西编号,然后模拟存入取出就行了. 定义map <pair <int,int>,int> p 来表示,p[{i,j}] 表示第 i*,j* 个柜子的第 i,j 个格子的物品j就可以了.

完整代码如下:

#include<bits/stdc++.h>
using namespace std;
int main(){
    map<int,map<int,int> >a;   //创建二维映射
    int n,q,judge,num1,num2,staff;  
    cin>>n>>q; //输入
    for(int i=1;i<=q;i++){
        cin>>judge;
        if(judge==1){
            cin>>num1>>num2>>staff;
            a[num1][num2]=staff;  //存入东西
        }
        else{
            cin>>num1>>num2;
            cout<<a[num1][num2]<<endl;   //输出存入的东西
        }
    }
    system("pause");
    return 0;
}

2.括号序列

题目描述

定义如下规则:

  1. 空串是「平衡括号序列」
  2. 若字符串 S 是「平衡括号序列」,那么 {[}] 和 {(}) 也都是「平衡括号序列」
  3. 若字符串 A 和 B 都是「平衡括号序列」,那么 AB(两字符串拼接起来)也是「平衡括号序列」。

例如,下面的字符串都是平衡括号序列:

()[](())([])()[]()[()]

而以下几个则不是:

([])(())([()

现在,给定一个仅由 ()[]构成的字符串 s,请你按照如下的方式给字符串中每个字符配对:

  1. 从左到右扫描整个字符串。
  2. 对于当前的字符,如果它是一个右括号,考察它与它左侧离它最近未匹配的的左括号。如果该括号与之对应(即小括号匹配小括号,中括号匹配中括号),则将二者配对。如果左侧未匹配的左括号不存在或与之不对应,则其配对失败。

配对结束后,对于 s 中全部未配对的括号,请你在其旁边添加一个字符,使得该括号和新加的括号匹配。

输入格式

输入只有一行一个字符串,表示 s。

输出格式

输出一行一个字符串表示你的答案。

样例 #1

样例输入 #1

([()

样例输出 #1

()[]()

样例 #2

样例输入 #2

([)

样例输出 #2

()[]()

提示

数据规模与约定

对于全部的测试点,保证 s 的长度不超过 100,且只含 ()[] 四个字符。

对于这一道题我已经无语了,题目解释的实在是不清楚,我实在不知道我错在哪里,所以这里我就应用这道题题解中的这个大佬的题解再次解释一下:扫描一遍原序列,当找到一个右括号(即找到一个 ’ ) ’ 或者 ’ ] ’ 时),以它为起点向左找,找到一个没被标记成功匹配的左括号(即找到一个 ’ ( ’ 或者 ’ [ ’ ),如果两者匹配的话,标记它们成功 牵手 匹配,如果不匹配,或者找不到左括号的话,不做任何标记。上面扫描一遍标记完成功匹配的括号之后,扫描一遍序列,对于标记过的括号,则直接输出;对于没有标记的括号,则补全成对输出

例如:

输入:( [ ) ] )

输出:( [ ( ) ] )

所以在了解完题目在说什么后,我们就可以很快的想出思路:首先我们从开头开始遍历,如果找到一个右括号(“)“或者”]”),则以它为起点向左检索,如果找到了第一个左括号是与之匹配且没有配对成功,则让它们配对.如果第一个找到的左括号是不与之匹配的而且没有成功配对的,或者遍历到头也没找到左括号,则不做处理,.这里我用一个book数组来标记配对成功的括号.

完整代码如下:

#include<bits/stdc++.h>
using namespace std;    
string s;
int book[100]={0};  //标记数组
void judge(){  
    for(int i=0;i<=s.length()-1;i++){           
        if(book[i]==0){
            int u=i;
            if(s[i]==
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值