题目如下
经过分析本题符合栈后进先出的特点(LIFO)
故先输入并手动建栈;
并且本题为避免最后无法配对的情况,需运用返回状态和双向遍历。
while(scanf("%c",&a)!=EOF)
{
k[++top]=a;
}
uu=top;
top++;
uu相当于一个标记用于返回某一个状态的栈。
入栈完毕后进行出栈操作并记录面积。
注意:由于C++中\是转义运算符,所以在判定’‘时用’\'代替。
while(top--!=1)
{
if(k[top]=='/')
{
flag=1;
num1++;
y++;
ans[i]+=y-0.5;
}
if(k[top]=='\\')
{
if(flag==1)
{
num2++;
ans[i]+=y-0.5;
y--;
}
}
if(k[top]=='_')
{
if(flag==1)
{
ans[i]+=y;
}
}
if(num1==num2 && num1!=0)
{
tot+=ans[i];
y=0;
i++;
flag=0;
num1=0;
num2=0;
uu=top;
}
}
因为出栈是从右往左扫,因此若先扫到’\‘则不必记录,若扫到’/‘将标记flag改为1;开始记录’\’’,用y记录面积’’/‘向下深入y++,’\‘向上返回y–,’_’,不动,但面积因加上长方形;
num1==num2时开始计算面积;
if(num2!=num1)
{
num1=0;
num2=0;
kans[j]=0;
y=0;
top=-1;
flag=0;
while(top++!=uu)
{
if(k[top]=='\\')
{
flag=1;
num1++;
y++;
kans[j]+=y-0.5;
}
if(k[top]=='/')
{
if(flag==1)
{
num2++;
kans[j]+=y-0.5;
y--;
}
if(k[top]=='_')
{
if(flag==1)
{
kans[j]+=y;
}
}
if(num1==num2 && num1!=0)
{
tot+=kans[j];
y=0;
j++;
flag=0;
num1=0;
num2=0;
u=0;
}
}
}
}
最后一般有一种无法配对,因此这个时候就需要用到我们的uu状态,从0开始反向遍历到栈顶为uu时的状态,因为反向所以’/‘要相当于’\’,’\‘相当于’/’;
cout<<tot<<endl;
cout<<i+j<<" ";
for(int qq=0;qq<=j-1;qq++)
{
cout<<(long long)kans[qq]<<" ";
}
for(int pp=i-1;pp>=0;pp--)
{
cout<<(long long)ans[pp]<<" ";
}
因为前面有0.5参与运算,定义为float类型,输出需要用到强转。