队列问题
队列,即为先进先出的数据结构,需要设定两个下标指针,一个为front,指向要pop的元素,另一个为rear,指向即将进入的新元素。实现这个数据结构也十分简单,代码省略。但是如果简单的采用线性队列那么之前使用过并被释放的元素位置不能被再次使用(如下)
-1 | -1 | -1 | 5 | 7 | 9 |
此时如果-1代表用过的位置的话那么-1的位置不会重复使用,则会造成资源浪费,所以我们可以将队列设计成环形的队列,每次取元素就对maxn(队列大小)取余作为下标。那么我们需要解决一个问题,就是如何判断此队列是否已经满了,可否再装元素了,其实树上给出的解决方法是少用一个元素的位置,这样判断就可以用if((rear+1)%maxn==front)那么这个队列就满了。(可以避免一开始front和near都为0的状况。)但是刚才我又想到了一种方法,就是判断near-front<=maxn是否成立,但是这种做法的弊端在于当进入队列的数足够多时,rear和front可能会炸掉。
### 封闭面积问题
判断星号围成的面积的大小
【输入格式】
M N 之后是m*n的表,为要计算的表中的大小
【样例输入】
4 3
c++
0 0 0 0
0 * * 0
* 0 * 0
【样例输出】
1
题解
实际上这题的基本思路就是从某一个角开始向整个数组开始搜索,然后为0的放入队列中,然后下一次再从队列中寻找下面的为0的元素,并把搜索过的设为1,由于围成的面积必定隔着一个星号,所以不可能搜索到围成的面积里面的东西。
code
#include<iostream>
#include<cstdlib>
#include<cstring>
#define maxn 90000
using namespace std;
struct img{
short int x;
short int y;
}a[maxn];
int main(void)
{
char temp;
short int dx[4]={0,1,0,-1}; //这样写搜4周比较省事hhh
short int dy[4]={1,0,-1,0};
int m,n,tt,kk,xing=0,ttxx,ttyy;
cin>>m>>n;
bool pos[n+2][n+2];
memset(pos,0,sizeof(pos));
int i,j;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
cin>>temp;
if(temp=='*')
{
pos[i][j]=1;
xing++;
}
else if(temp=='0')
pos[i][j]=0;
}
}
for(i=1;i<=n+1;i++) //avoid 数组越界
{
pos[i][m+1]=1;
}
for(i=1;i<=m+1;i++)
{
pos[n+1][i]=1;
}
for(i=0;i<=m+1;i++)
{
pos[0][i]=1;
}
for(i=1;i<=n+1;i++)
{
pos[i][0]=1;
}
int sum=1,front,rear;
tt=1;kk=1;a[1].x=1;
a[1].y=1;
pos[1][1]=1;
while(tt<=kk) //tt记录搜索的次数,kk记录搜索到的星
{
for(i=0;i<=3;i++) //尝试4个方向
{
front=tt%maxn;
ttxx=a[front].x+dx[i];
ttyy=a[front].y+dy[i];
if(pos[ttyy][ttxx]==0)
{
kk++;
rear=kk%maxn;
a[rear].x=ttxx;
a[rear].y=ttyy;
sum++;
pos[ttyy][ttxx]=1;
}
}
tt++;
}
cout<<m*n-sum-xing<<endl;
return 0;
}