一、关于栈:
FILO (First In Last Out)
二、专题练习&题解:
(没错我懒了,具体介绍搜就行)
1.栈-程序员输入问题
这里要注意最好不要用单个字符在输入时就做判断(TLE,我也不知道为啥),而且cin读单个字符,敲下回车是不会读入’\n’的。
#include <bits/stdc++.h>
using namespace std;
int main()
{
stack<char>str,str1;
char a[101];
gets(a); //字符串含空格
for(int i=0;i<strlen(a);i++)
{
if(a[i]=='@')
while(!str.empty())
{str.pop();continue;}
if(a[i]=='#')
{str.pop();continue;}
if(a[i]!='#'&&a[i]!='@')
str.push(a[i]);
}
while(!str.empty())
{
str1.push(str.top());
str.pop();
}
while(!str1.empty())
{
cout<<str1.top();
str1.pop();
}
return 0;
}
2.栈-溶液模拟器
没用栈写,所以可能繁琐一点。思路就是输入P就输入加的V和C,再计算并记录加完后的V和C,遇到Z就输出上一次的记录。
#include <bits/stdc++.h>
using namespace std;
struct yeti
{
char ch;
int vi,vz;
double ci,cz;
}x[10005];
int main()
{
int v0,n;
double c0;
cin>>v0>>c0>>n;
for(int i=1;i<=n;i++)
{
getchar();
cin>>x[i].ch;
if(i==1&&x[i].ch=='Z')
{
printf("%d %.5lf\n",v0,c0);
i-=1;n-=1; //因为Z没有输入,所以在该i值情况下没有输入,让i-1保持上次的记录;又因为Z也是一次
continue; //操作,所以n-1;
}
if(i!=1&&x[i].ch=='Z')
{
if(i-2!=0) //为什么是-2在纸上算一下即可
printf("%d %.5lf\n",x[i-2].vz,x[i-2].cz);
else
printf("%d %.5lf\n",v0,c0);
i-=2;n-=2;
continue;}
if(i==1&&x[i].ch=='P')
{
cin>>x[i].vi>>x[i].ci;
x[i].vz=v0+x[i].vi;
x[i].cz=(c0*v0*0.01+x[i].vi*x[i].ci*0.01)/(x[i].vz)*100; //此处注意*0.01再计算才有小数位变化
printf("%d %.5lf\n",x[i].vz,x[i].cz);
}
if(i!=1&&x[i].ch=='P')
{
cin>>x[i].vi>>x[i].ci;
x[i].vz=x[i-1].vz+x[i].vi;
x[i].cz=(x[i-1].cz*x[i-1].vz*0.01+x[i].vi*x[i].ci*0.01)/(x[i].vz)*100;
printf("%d %.5lf\n",x[i].vz,x[i].cz);
}
}
return 0;
}
3.栈-火车编组
我真是服了这题的描述,看了好一会才懂说的是啥意思:按升序进行进出栈操作,使得操作完成后出栈排成的序列为输入的序列。例如输入3 2 4 1,则1、2、3先进栈(AAA),3、2再出栈(BB),4再进栈(A),4、1最后出栈(BB),则出栈顺序为3 2 4 1,所以AAABBABB。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, str[105], t;
stack<int> temp, final;//temp进,final出
while (cin >> n)
{
int pos=1; //作为一个“指针”
for (int i = 1; i <= n; i++)
cin >> str[i];
for (int i = n; i >= 1; i--)
temp.push(i);
while (!temp.empty())
{
//思路是让所有<=str[i]的车厢先进栈,然后让等于str[i]的车厢出栈
if (temp.top() <= str[pos])
{
t = temp.top();
final.push(t);
temp.pop();
cout << "A";
}
if (final.top() == str[pos])
{
final.pop();
cout << "B";
pos++;
}
}
while (!final.empty()) //保证所有车厢全部出栈
{
cout << "B";
final.pop();
}
cout << endl;
}
return 0;
}
4.栈-洗盘子
需注意是“输入若干行”
#include <bits/stdc++.h>
using namespace std;
int str[10005][2];
int main()
{
ios::sync_with_stdio(false);
int n;
stack<int> initial, wash, wipe;
while (cin >> n)
{
int total = 0, pos = 0;//pos记录输入的行数
int ans;
for (int i = 1;; i++)
{
cin >> str[i][0] >> str[i][1];
pos++;
if (str[i][0] == 2)//当盘子擦完,停止输入
{
total += str[i][1];
if (total == n)
{
break;
}
}
}
for (int i = n; i >= 1; i--)
initial.push(i);
for (int i = 1; i <= pos; i++)
{
if (str[i][0] == 1)//==1时从initial进wash
{
while (str[i][1]--)
{
wash.push(initial.top());
initial.pop();
}
}
else//==2时从wash进wipe
{
while (str[i][1]--)
{
wipe.push(wash.top());
wash.pop();
}
}
}
while (n--)//最后输出
{
ans = wipe.top();
wipe.pop();
cout << ans << endl;
}
}
return 0;
}
5.栈-括号匹配
“消消乐”?从内往外消对子,有剩的就Wrong了
#include <bits/stdc++.h>
using namespace std;
int main()
{
string str;
cin>>str;
stack<char> temp;
for (int i = 0; i < str.size(); i++)
{
if (str[i] == '(' || str[i] == '['||temp.empty()//有一开始为')',']'的情况)
{
temp.push(str[i]);
continue;
}
if (temp.top() == '(' && str[i] == ')')
temp.pop();
else if (temp.top() == '[' && str[i] == ']')
temp.pop();
else
temp.push(str[i]);
}
if (temp.empty())
cout << "OK" << endl;
else
cout << "Wrong" << endl;
return 0;
}
6.栈-表达式求值
注意乘法的优先级
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e4;
int main()
{
int x, t, ans = 0;
char ch;
cin >> x;
t = x % mod;
while (scanf("%c", &ch) && ch != '\n') //这里不能用cin,cin读入回车不是'\n'
{
cin >> x;
x = x % mod;
if (ch == '*')
t = t * x % mod;
else
{
ans = ans + t % mod;
t = x;
}
}
ans = ans + t;
cout << ans % mod << endl;
return 0;
}
时隔一个月,我终于把这章补完了,竟无聊到学习。这假越过越长?