4.23洛谷刷题总结

目录

1.# 填涂颜色

思路分析

代码示例

2.# 后缀表达式

思路分析

代码示例

3.# 【深基15.例2】寄包柜

思路分析

代码示例


1.# 填涂颜色

## 题目描述

由数字 $0$ 组成的方阵中,有一任意形状的由数字 1构成的闭合圈。现要求把闭合圈内的所有空间都填写成 $2$。例如:6* 6的方阵(n=6),涂色前和涂色后的方阵如下:

如果从某个 $0 出发,只向上下左右 $4$ 个方向移动且仅经过其他 $0$ 的情况下,无法到达方阵的边界,就认为这个 $0$ **在闭合圈内**。闭合圈不一定是环形的,可以是任意形状,但保证**闭合圈内**的 $0$ 是连通的(两两之间可以相互到达)。

```plain
0 0 0 0 0 0
0 0 0 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 1 0 1
1 1 1 1 1 1
```
```plain
0 0 0 0 0 0
0 0 0 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 1 2 1
1 1 1 1 1 1
```

## 输入格式

每组测试数据第一行一个整数 $n(1 \le n \le 30)$。

接下来 $n$ 行,由 $0$ 和 $1$ 组成的 $n \times n$ 的方阵。

方阵内只有一个闭合圈,圈内至少有一个 $0$。

## 输出格式

已经填好数字 $2$ 的完整方阵。

## 样例 #1

### 样例输入 #1

```
6
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1
```

### 样例输出 #1

```
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 2 2 1
1 1 1 1 1 1
```

## 提示

对于 %100 的数据,1 \le n \le 30。

思路分析

1,首先在这个矩阵里会出现俩种0,一种是在外围的0,也就是在1所包围的外面,还有一种就是被1所包围的0,如果能够区别出这俩种0,那么里面的0自然也就可以判断并染色了

2,开始用bfs广度搜索,如果直接搜圈内的0的话比较麻烦,所以在这里我们先在矩阵的外面(是矩阵的外面就是再矩阵增加一个圈,用0把矩阵围住)

3.这时侯我们从矩阵的第一个0开始搜索,将所有1外围的0搜完并标记成2,然后搜不到的那肯定就是圈内的0,所以此时输出只需输出矩阵就可,且输出的矩阵中的每个元素用2去减掉,这时圈内的0就会被染成2了

代码示例

#include<bits/stdc++.h>
using namespace std;
int mp[42][42];//地图数组
int vis[42][42];//标记数组
int n;//总体思路给整个地图的边界围一圈0,然后,搜不到的地方默认为被1围住的区域,然后边界赋值为2,最后不输出边界围的那一圈0

int dre[4][2]={{0,1},{1,0},{0,-1},{-1,0}};

struct node
{
    int x,y;
};
bool judge(int x,int y)
{
    if(x<0||x>n+1||y<0||y>n+1)return false;

    if(vis[x][y]==1||mp[x][y]==1)return false;
    return true;
}
void bfs(int x,int y)
{
    queue<node>q;
    node temp;
    temp.x=x;
    temp.y=y;
    q.push(temp);
    vis[x][y]=1;
    while(!q.empty())
    {
        node t=q.front();
        mp[t.x][t.y]=2;
        q.pop();
        for(int i=0; i<4; i++)//方向数组遍历
        {
            int xx=t.x+dre[i][0];
            int yy=t.y+dre[i][1];
            if(judge(xx,yy))
            {
                vis[xx][yy]=1;
                temp.x=xx;
                temp.y=yy;
                q.push(temp);//存入队列
            }
        }
    }
}

int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
            cin>>mp[i][j];
    bfs(0,0);
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            cout<<2-mp[i][j]<<" ";//输出
        }
        cout<<"\n";
    }
  return 0;
}

2.# 后缀表达式

## 题目描述

所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右新进行(不用考虑运算符的优先级)。

本题中运算符仅包含{+-*/}。保证对于 $\texttt{/}$ 运算除数不为 0。特别地,其中/ 运算的结果需要向 0 取整(即与 C++ `/` 运算的规则一致)。

如:{3*(5-2)+7}对应的后缀表达式3.5.2.-*7.+@}$。在该式中,`@` 为表达式的结束符号。`.` 为操作数的结束符号。

## 输入格式

输入一行一个字符串 $s$,表示后缀表达式。

## 输出格式

输出一个整数,表示表达式的值。

## 样例 #1

### 样例输入 #1

```
3.5.2.-*7.+@
```

### 样例输出 #1

```
16
```

## 样例 #2

### 样例输入 #2

```
10.28.30./*7.-@
```

### 样例输出 #2

```
-7
```

## 提示

数据保证,$1 \leq |s| \leq 50,答案和计算过程中的每一个值的绝对值不超过 10^9。

思路分析

1,我们用数组模拟一个栈,首先先判断进来的是不是数字字符,如果进来的字符是数字字符的话,那么用一个整形变量来存储这个数字字符在输入数据结束后得到的值

2,然后判断输入数字数据结束,如果遇到‘.’号结束符号的话,把刚刚保存的值存进栈顶去存进sta[++i];

3.接下来我们开始判断运算字符,在判断字符的过程中,遇到一个运算符,就取出栈顶的俩个元素进行运算,运算后再存入栈顶,然后把之前用来存入数字字符的值的变量num赋值为0,把之前参与运算的栈元素赋值为0,例,如果是栈顶和栈的第二个元素运算的话,结果存入栈顶,栈的第二个元素赋值为0

代码示例

#include<bits/stdc++.h>
using namespace std;
long long sta[1000];
int main(){
   long long i=0,now=0;
   char op;
   while((op=getchar())!='@'){
     if(op>='0'&&op<='9'){
        now*=10;
        now+=op-'0';
     }
     else if(op=='.'){
        sta[++i]=now;
        now=0;
     }
     else if(op=='+'){
         sta[i-1]=sta[i-1]+sta[i];
         sta[i]=0;
         i--;
     }
      else if(op=='-'){
         sta[i-1]=sta[i-1]-sta[i];
         sta[i]=0;
         i--;
     }
      else if(op=='*'){
         sta[i-1]=sta[i-1]*sta[i];
         sta[i]=0;
         i--;
     }
      else if(op=='/'){
         sta[i-1]=sta[i-1]/sta[i];
         sta[i]=0;
         i--;
     }
   }
   cout<<sta[1];
   return 0;
}
 

3.# 【深基15.例2】寄包柜

## 题目描述

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

- `1 i j k`:在第 $i$ 个柜子的第 $j$ 个格子存入物品 $k(0\le k\le 10^9)$。当 $k=0$ 时说明清空该格子。
- `2 i j`:查询第 $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
```

## 提示

$\text{upd 2022.7.26}$:新增加一组 Hack 数据。

思路分析

1.用一个数组来存放寄包柜,然后通过1和2来判断他的操作,如果是1的话输入p,q,t的值来对数组进行存放,如果是2的话则输入p,q来查询a数组中a[p][q]的值

代码示例

#include<bits/stdc++.h>
using namespace std;
int n,m,k;
int p,q,t;
map<int,map<int,int>>a;
int main(){
 cin>>n>>m;
 for(int i=0;i<m;i++)
 {
     cin>>k;
     if(k==1){
            cin>>p>>q>>t;
            a[p][q]=t;
     }
     if(k==2){
           cin>>p>>q;
           cout<<a[p][q]<<endl;

     }
 }




}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值