今天学了栈,以及AC的一道题
栈的概念:
栈(Stack):是只允许在一端进行插入或删除的线性表。首先栈是一种线性表,但限定这种线性表只能在某一端进行插入和删除操作。简单来说就是先进后出或者后进先出的线性表,简称LIFO结构
栈顶:线性表允许进行插入删除的那一端。
栈底:固定的,不允许进行插入和删除的另一端。
栈的一些基本操作:
#include "iostream"
#define maxsize 10 //定义栈中元素的最大个数
typedef struct Node {
int data[maxsize]; //静态数组存放栈中元素
int top; //栈顶指针
}Sqstack;
bool stackempty(Sqstack s) { //判断栈空
if (s.top == -1)
return true; //栈空
else
return false; //不空
}
void initstack(Sqstack& s) { //初始化栈
s.top = -1; //初始化栈顶指针
}
void teststack() {
Sqstack s; //声明一个顺序栈(分配空间)
initstack(s);
}
bool Push(Sqstack& s, int x) { //新元素入栈
if (s.top == maxsize-1) //栈满,报错
return false;
s.top = s.top + 1; //指针先加一
s.data[s.top] = x; //新元素入栈
return true;
}
bool Pop(Sqstack& s, int x) { //出栈(删)
if (s.top == -1) //栈空,报错
return false;
x = s.data[s.top]; //栈顶元素先出栈
s.top = s.top - 1; //指针再减一
return true; //(所以出栈的删除是从逻辑上来说删除了,物理意义伤还在)
}
bool Gettop(Sqstack& s, int x) { //读栈顶元素
if (s.top == -1) //栈空,报错
return false;
x = s.data[s.top]; //x记录栈顶元素
return true;
}
int main() {
teststack();
}
AC的题目描述
由数字 0 组成的方阵中,有一任意形状的由数字 11 构成的闭合圈。现要求把闭合圈内的所有空间都填写成 2。例如:6×66×6 的方阵(n=6),涂色前和涂色后的方阵如下:
如果从某个 0 出发,只向上下左右 4个方向移动且仅经过其他 0 的情况下,无法到达方阵的边界,就认为这个 0 在闭合圈内。闭合圈不一定是环形的,可以是任意形状,但保证闭合圈内的 0 是连通的(两两之间可以相互到达)。
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
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
输入格式
每组测试数据第一行一个整数 (1≤≤30)n(1≤n≤30)。
接下来 n 行,由 0 和 1 组成的 n×n 的方阵。
方阵内只有一个闭合圈,圈内至少有一个 00。
输出格式
已经填好数字 22 的完整方阵。
输入输出样例
输入 #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≤n≤30。
没错这是一道bfs题;以为很简单的一道题却被坑了;简单的以为只需要从(1,1)开始广搜,如果是0就标记一下3,直到碰见1或者越界便return;最后在输出的时候判断如果是3就输出0,是0输出2即可;交上去发现只对了两个测试,看了一个错误的测试结果,转动脑袋一想,bfs不能只从(1,1)开始,要将外围的一圈都进行bfs;最终交上去AC了。
AC代码:
#include <iostream>
#include <string>
#include <cmath>
#include <iomanip>
#include <algorithm>
#include <stack>
using namespace std;
using ll = long long;
#define up(h,n) for(int i=h;i<=n;i++)
#define down(h,n) for(int i=h;i>=n;i--)
#define wh(x) while(x--)
#define node struct node
#define ios ios::sync_with_stdio(false)
constexpr int N = 18;
constexpr int mod = 1e9 + 7;
int next2[4][2] = { {-1,0},{1,0},{0,-1},{0,1} }; //四个方向
int a[32][32];
int book[32][32];
int n;
void bfs(int x, int y)
{
if (a[x][y] == 1 || x<1 || x>n || y<1 || y>n) return; //判断是否越界
book[x][y] = 1;
a[x][y] = 3;
up(0, 3) { //遍历四个方向
int tx = x + next2[i][0];
int ty = y + next2[i][1];
if (tx<1 || tx>n || ty<1 || ty>n || a[tx][ty] == 1)
continue ;
if (book[tx][ty] == 0 && a[tx][ty] == 0){
a[tx][ty] = 3; //在闭合圈外标记3
book[tx][ty] = 1; //标记这个点已经走过
bfs(tx, ty);
book[tx][ty] = 0;//回溯
}
}
return;
}
int main()
{
cin >> n;
up(1, n) {
for (int j = 1; j <= n; j++)
cin >> a[i][j];
}
up(1, n) {
bfs(1, i); bfs(n, i);
}
up(2, n - 1) {
bfs(i, 1); bfs(i, n);
} //将外围一圈都bfs一下
up(1, n) {
for (int j = 1; j <= n; j++) {
if (a[i][j] == 3) cout << 0 << ' ';
else if (a[i][j] == 1) cout << a[i][j] << ' ';
else cout << 2 << ' ';
}
cout << '\n';
}
return 0;
}