P3613 寄包柜
题目
难点
原本以为:寄包柜这个输入输出非常复杂,数据蛮大的题是四道题中最难的一道,放在了最后做,但是很快理解了这道题:实际上是要创建一个很大的二维数组,存放寄包柜与格子,可是,用二维数组很明显无法开辟这么大的空间,因此需要用可变数组–vector来实现,这样,我们只需要创建一个嵌套容器,并使用resize函数重设vector的大小即可解决问题。
代码实现
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int n,q;
cin >> n >> q;
vector<vector<int> >a(n + 1);
while (q--)
{
int x, i, j, k;
cin >> x>>i>>j;
if (x == 1)
{
cin >> k;
//如果寄包柜不够大 那么就利用resize()函数重设寄包柜
if (a[i].size() < j + 1)
{
a[i].resize(j + 1);
}
a[i][j] = k;
}
else if (x == 2)
{
cout << a[i][j] << endl;
}
}
return 0;
}
P1449 后缀表达式
题目
解题思路
- 利用栈存储以 ‘ . ’ 字符间隔的数字
- 检索四则运算的符号,进行四则运算
难点分析
- 从一个字符串中取出数字存放在栈中,这有点类似与高精度数的存储,因为个位十位百位,所以不同的位数我们需要乘以不同的十的幂次,这一点比较难以实现,并且需要检索两个‘ . ’之间的数字序列,也需要合理的设置循环
代码实现
#include<iostream>
#include<stack>
#include<string>
#include<algorithm>
#include<cstdio>
using namespace std;
int main()
{
stack<int>stack;
string str;
cin >> str;
for (int i = 0; str[i] != '@'; i++)
{
int num = 0;
int beishu = 1;
//书写if时,我们需要考虑清楚:if的条件应该有几个,也就是str[i]会出现几种情况
//1、str[i]=='.'
//2、str[i] >= '0' && str[i] <= '9'
//3、str[i]是四则运算符之一
//因此,我们需要考虑清楚这三种情况中,if应该执行的语句
//1、出现.时,应该将两个点之间的字符串型数字转为整型数字压入栈
//2、出现数字时,不理会
//3、出现四则运算时,设计四则运算
if (str[i] == '.')
{
for (int j = i - 1; str[j] >= '0' && str[j] <= '9'; j--)
{
//借此保留一下位数 用倍数的逐增记录
num += (str[j] - 48) * beishu;
beishu *= 10;
}
stack.push(num);
}
else if (str[i] >= '0' && str[i] <= '9')continue;
else
{
//根据后缀表达式,取且仅取栈顶的两个元素作为操作数
//先利用一个k存储栈顶元素并令这个栈顶元素出栈
int k = stack.top();
stack.pop();
//同时使用ans存储这次操作后的结果 并在最后将ans压入栈
int ans = 0;
if (str[i] == '+')
{
ans = k + stack.top();
stack.pop();
}
else if (str[i] == '-')
{
//根据先进后出原则,栈顶取出的元素即k应该是减数与除数
//后续取出的元素应该是被减数与被除数
ans = stack.top()-k;
stack.pop();
}
else if (str[i] == '/')
{
ans = stack.top() /k;
stack.pop();
}
else if(str[i]=='*')
{
ans = k * stack.top();
stack.pop();
}
stack.push(ans);
}
}
cout << stack.top() << endl;
return 0;
}
难点解决
int num = 0;
int beishu = 1;
if (str[i] == '.')
{
for (int j = i - 1; str[j] >= '0' && str[j] <= '9'; j--)
{
//借此保留一下位数 用倍数的逐增记录
num += (str[j] - 48) * beishu;
beishu *= 10;
}
stack.push(num);
}
我们在累计压入栈的数字时,可以记录一个倍数,由于是从右向左检索字符串,也即先查找个位数,再查找十位数,那么,我们所累计的乘数–倍数,就应该从1开始逐个乘十,借此来正确的表达数位。
P1241 括号序列
解题思路
- 设置一个结构体,写入一个sic来保存是否这个括号是否被配对
- 遍历全部的括号,写入sic的情况(配对后写入1,未配对写入0)
- 遵照sic,设置不同的输出情况
代码实现
#include<iostream>
using namespace std;
struct kuohao {
char a;
int sic=0;
};
int main()
{
struct kuohao arr[105];
int len = 0;
arr[len].a = getchar();
arr[len].sic = 0;
while (arr[len].a != '\n')
{
len++;
arr[len].a = getchar();
arr[len].sic = 0;
}
//从左到右依次遍历全部的括号序列
for (int i = 0; i <= len; i++)
{
//找到右括号后,就开始从右括号的左边寻找到第一个左括号,并且,无论
//是否能够正确配对,都要结束寻找左括号,我们只找最近的那个未配对左括号
if (arr[i].a == ')' || arr[i].a == ']')
{
for (int j = i - 1; j >= 0; j--)
{
if ((arr[j].a == '(' || arr[j].a == '[')&&arr[j].sic!=1)
{
if (arr[j].a == '(' && arr[i].a == ')')
{
arr[j].sic = 1;
arr[i].sic = 1;
break;
}
else if (arr[j].a == '[' && arr[i].a == ']')
{
arr[j].sic = 1;
arr[i].sic = 1;
break;
}
else break;
}
}
}
}
//检验并输出
for (int i = 0; i <= len; i++)
{
if (arr[i].sic == 1)
{
cout << arr[i].a;
}
else
{
if (arr[i].a == '(' || arr[i].a == ')')
cout << "()";
else if (arr[i].a == '[' || arr[i].a == ']')
cout << "[]";
}
}
return 0;
}
P1160 队列安排
题目
解题思路
QAQ,解题思路完全遵照祝神给的markdown文件照抄所以orz润一下解题思路
代码实现
#include<iostream>
#include<vector>
using namespace std;
const int mx = 1e5 + 10;
struct student {
int l, r;
int d;
}stu[mx]={0};
//i表示第几号同学,k表示i要插入的同学,p是i要插入k的左边还是右边的标志
void add(int i, int k, int p)
{
//p=0,表明要插在k号同学的左手边,那么,i同学的右手将拉k同学的左手,i同学的左手将拉k同学左手拉的同学
//如此一来,k同学右手拉的同学的右手应该拉i同学的左手
//同时,k同学的左手应该拉i同学
if (p == 0)
{
stu[i].r = k;
stu[i].l = stu[k].l;
stu[stu[i].l].r = i;
stu[k].l = i;
}
//如果插入k同学的右边 那么 i同学的左手拉k同学的右手
//i同学的右手拉k同学右手拉的同学
//同时,k同学原来右手边的同学,也就是i同学现在右手边的同学的左手应该拉i
//且,k同学的右手应该拉i同学
else
{
stu[i].l = k;
stu[i].r = stu[k].r;
stu[stu[i].r].l = i;
stu[k].r = i;
}
}
//x是要删除的同学
void del(int x)
{
stu[x].d = 1;
}
int main()
{
int n = 0; cin >> n;
add(1, 0, 1);
for (int i = 2; i <= n; i++)
{
int k, p;
cin >> k >> p;
add(i, k, p);
}
int m; cin >> m;
while (m--)
{
int x; cin >> x;
del(x);
}
for (int i = stu[0].r; i; i = stu[i].r)
{
if (stu[i].d != 1)
cout << i<<" ";
}
return 0;
}